There are some query that have same part of where clause on.
Query one:
select [some-selected column]
from [TABLE_NAME]
where [its-own-where-clause]
and [shared-where-clause]
Query two:
select [some-selected column]
from [TABLE_NAME]
where [its-own-where-clause]
and [shared-where-clause]
Query three:
select [some-selected column]
from [TABLE_NAME]
where [its-own-where-clause]
and [shared-where-clause]
.
.
.
.
Query n:
select [some-selected column]
from [TABLE_NAME]
where [its-own-where-clause]
and [shared-where-clause]
As you can see there are two parts in the where-clause, the first one is belong to its own business of query and the second one is shared between all of these querys.
It is clear that the all of above query must be changed when [shared-where-clause] is changed.
I want to put the shared-section of where-clause in which the change of it is applied to all of this querys.
Is it possible in oracle?
Create a VIEW.
Example:
create table PERSON (
PERSON_ID number(10, 0) not null primary key,
PERSON_NAME nvarchar(100) not null,
AGE number(3, 0) not null,
GENDER char(1) not null check(GENDER in ('M', 'F'))
);
create view MALES as
select PERSON_ID, PERSON_NAME, AGE, GENDER
from PERSON
where GENDER = 'M';
create view FEMALES as
select PERSON_ID, PERSON_NAME, AGE, GENDER
from PERSON
where GENDER = 'F';
Now we can query various age groups of male persons without repeating the shared condition on GENDER.
select *
from MALES
where AGE between 0 and 19;
select *
from MALES
where AGE between 20 and 49;
select *
from MALES
where AGE >= 50;
Related
I am using the below query in a prepared statement. Earlier I was using in procedure and using callable but now I am trying to use select query in jdbc prepared statement.
I know in preparestatement we write insert into abc values(?,?,?);
but here I have insert-select. same variable has been used many places. in this query I have 2 variable
p_entity_type and p_update_mode
INSERT INTO dynamicEntitynotgett
(entity_type, entity_id, entity_code, synonyms, action)
WITH data_view AS
( -- ITEM table
SELECT 'ITEM' entity_type, -- This separates inserted values
item_id data_id,
item_name data_name,
item_desc data_desc,
creation_date
FROM itemde
UNION ALL
-- ORG table
SELECT 'ORG' entity_type, -- This separates inserted values
org_id,
org_name,
org_desc,
creation_date
FROM orgde
UNION ALL
-- Feature table
SELECT 'FEATURES' entity_type, -- This separates inserted values
FEATURE_id data_id,
FEATURE_NAME data_name,
FEATURE_DESC data_desc,
CREATION_DATE
FROM FEATURESDE
)
SELECT upper(t.entity_type),
t.data_id,
t.data_name,
t.data_desc,
CASE lower(p_update_mode)
WHEN 'INCREMENTAL' THEN
CASE
WHEN t.creation_date > b.last_update_date THEN
'update'
WHEN t.creation_date < b.last_update_date THEN
'add'
END
WHEN 'full' THEN
'add'
END action
FROM data_view t
LEFT JOIN ODA_REFRESH_DETAILS b
ON b.entity_type = t.entity_type
AND lower(p_update_mode )='incremental'
WHERE (upper(p_entity_type) = t.entity_type OR p_entity_type IS NULL)
AND (lower(p_update_mode) = 'full'
OR (lower(p_update_mode) = 'incremental' AND b.entity_type IS NOT NULL)
);
I will receive p_entity_type and p_update_mode from upper stream. which solution would be better? Resultset or Preparedstatement and how can I replace those values in query or use setXXX().
I think you are looking for namedParameterStatement. This would allow you to name the parameters.
I'm not exactly sure what you are referring to in your statement, but for instance, this line:
SELECT 'ITEM' entity_type
could be replaced with:
SELECT :ITEM as entity_type
where :ITEM is passed in just like a ?, but could be used multiple times in the statement.
I have a database table like this
Users
id Capacity Gender
----------------------
1 10 M
---------------------
2 9 M
---------------------
3 4 F
---------------------
4 8 M
---------------------
5 7 F
---------------------
And I want to retrieve the top 3 records ordered by capacity and with at least one from opposite gender using SQL, like below
id Capacity Gender
----------------------
1 10 M
---------------------
2 9 M
---------------------
5 7 F
---------------------
I cant user 'partition by' since i'm not using oracle, I want one that works for H2 database, or database agnostic if possible.
Thanks in advance
Sam
This is quite long since the requirement is also strict.
It is making use of self join and group by.
Get the top 2 per gender to ensure that both gender group is represented. Then get top 3.
SELECT id, capacity, gender
from (
SELECT t.id, t.gender, t.capacity,
COUNT(*) AS rn
FROM t
JOIN t AS t2
ON t2.gender = t.gender
AND ( t2.capacity > t.capacity
OR t2.capacity = t.capacity
AND t2.id <= t.id )
GROUP BY t.id, t.gender, t.capacity
HAVING COUNT(*) <= 2
ORDER BY t.capacity desc, rn ) tab
ORDER BY capacity desc
LIMIT 3;
Result:
id capacity gender
1 10 M
2 9 M
5 7 F
This might be a little bit hacky but works for your issue I believe. Please try:
CREATE TABLE temp as
Select top 2 id, Gender, max(capacity) as maxcap
from table
where Gender ='F'
group by id, Gender
CREATE TABLE temp2 as
Select top 2 id, Gender, max(capacity) as maxcap
from table
where Gender ='M'
group by id, Gender
select top 3 id, gender, maxcap
from
(
Select id, Gender, maxcap
from temp
union
Select Gender, maxcap
from temp2
) t
order by t.maxcap desc
Here's a CTE answer, based on David Conrad's approach from the comments:
with f(id, gender, capacity) as (select top 2 id, gender, capacity from capacity
where gender = 'F' order by capacity desc),
m(id, gender, capacity) as (select top 2 id, gender, capacity from capacity
where gender = 'M' order by capacity desc),
combined(id, gender, capacity) as (select * from f union select * from m)
select top 3 * from combined order by capacity desc;
(assuming the table is called "capacity" too). Without a RANK() function I can't see how to do any better, and I'm nervous about performance of the subquery count rank function suggested here on large tables, and you'll have to be careful about ties if you go down that route too. Tested on H2 and SQL Server.
I got these two tables and I want to have a query to count the amount of cars by each brand and insert this count to a column in the brand table
I've tried many queries but can't get it right.
First table,
Second table,
Use JOIN.
Query
select t1.car_brand_id, t2.brand_name, count(t1.car_name) as total_count
from table1 t1
join table2 t2
on t1.car_brand_id = t2.brand_id
group by t1.car_brand_id, t2.brand_name;
You need join count and group by
this is a select for see the count by brand_name
select b.brand_name, count(*)
from table_one a
inner join table_two b on b.brand_id = a.brand_id
group by b.brand_name
Once you have added the column you need in table_two ( with eg alter table command adding my_count_col)
you could use an update like this
update table_two
inner join (
select b.brand_name, count(*) my_count
from table_one a
inner join table_two b on b.brand_id = a.brand_id
group by b.brand_name ) t on t.brand_name = table_two.brand_name
set table_two.my_count_col = t.my_count
I have four columns, 2 columns lets say FIRST_NAME and LAST_NAME in table PersonalInfo and other 2 columns ADD1 and ADD2 in table AddressDetails. Now what I have to do is I want to know the count for duplicate record for each row considering all 4 columns.How can I do that?
I have 2 approach till now:
1. I iterate each response and compare with the remaining.
2. Do something with query.
I know the first case is worst option because it will take so much of the time. Is there something I can do with query?
I searched and found this:
SELECT LAST_NAME, count(LAST_NAME) FROM SchemaName.PersonalInfo S GROUP by LAST_NAME;
and the basic is working for single column and not for multiple columns.
How can I do it. Please suggest.
Group by all the cols not just last name.
Working fiddle : http://sqlfiddle.com/#!9/a76e7e/3
SELECT P.fname,P.lname,A.add1,A.add2, count(*)
FROM PersonalInfo P, AddressDetails A
Where P.id = A.id
GROUP by P.fname,P.lname,A.add1,A.add2
having count(*) > 1;
Join you tables on the id like in above example.
I suppose you table PersonalInfo has a primary key and AddressDetails ha a forey key on this primary key ?
select t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2, count(*) NbPossibility
from PersonalInfo t1 inner join AddressDetails t2
on t1.idPersonalInfo=t2.idPersonalInfo
group by t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2
having count(*)>1
Il you have not keys for join this tables (anormal):
select t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2, count(*) NbPossibility
from PersonalInfo t1 cross join AddressDetails t2
group by t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2
having count(*)>1
I have a table with name test in Oracle, and (sal(integer),gender) are the two columns in it.
I want to get counter number where gender is male, sal betwwen 1000,3000.
For example: If I have three people in table test (two male ,one female) and person1 sal =1000, person2 sal = 2020, person3 sal = 1040
The return value of sql statement will be equals (2).
The variable will store return value from java.
you actually want to count rows not column, as per what i understood from ur question. then you can use count(column_name) function of SQL along with the conditions (where clause).
Query: SELECT COUNT(*) "Count" FROM test WHERE gender='male' AND salary BETWEEN 1000 AND 3000
try this query,
select count(*) from <table_name> where gender='male' and salary between 1000 to 3000;