Whats wrong in this SQLite select statement? - select

I have two table:
Table1 is:
ID fname lname
---------------------
11 p1 p2
22 a1 a2
Table2 is:
ID fk_id field1 field2
------------------------------
1 11 2 3
2 22 5 4
and I have this statement in sqlite:
select * from Table1
where Table1.id=(select fk_id
from Table2
where (select sum([field1]-[field2])
from Table2 GROUP BY [fk_id]) > 0)
I expect that this query return all rows of Table1 but it return just one row!
why?!
I can't understand this!

It would help if there was the result.
So I guess because for table 11
sum(2 - 3) = -1
which fails for
select fk_id
from Table2
where (select sum([field1]-[field2])
from Table2 GROUP BY [fk_id]) > 0
So you only got 22 as your result.
You probably need a abs(sum([field1]-[field2]) then.

Related

Subsetting records that contain multiple values in one column

In my postgres table, I have two columns of interest: id and name - my goal is to only keep records where id has more than one value in name. In other words, would like to keep all records of ids that have multiple values and where at least one of those values is B
UPDATE: I have tried adding WHERE EXISTS to the queries below but this does not work
The sample data would look like this:
> test
id name
1 1 A
2 2 A
3 3 A
4 4 A
5 5 A
6 6 A
7 7 A
8 2 B
9 1 B
10 2 B
and the output would look like this:
> output
id name
1 1 A
2 2 A
8 2 B
9 1 B
10 2 B
How would one write a query to select only these kinds records?
Based on your description you would seem to want:
select id, name
from (select t.*, min(name) over (partition by id) as min_name,
max(name) over (partition by id) as max_name
from t
) t
where min_name < max_name;
This can be done using EXISTS:
select id, name
from test t1
where exists (select *
from test t2
where t1.id = t2.id
and t1.name <> t2.name) -- this will select those with multiple names for the id
and exists (select *
from test t3
where t1.id = t3.id
and t3.name = 'B') -- this will select those with at least one b for that id
Those records where for their id more than one name shines up, right?
This could be formulated in "SQL" as follows:
select * from table t1
where id in (
select id
from table t2
group by id
having count(name) > 1)

How to perform != or <> in postgresql

i need to fetch the table1 content which is not present in the table2 i dont think which is possible by <> or != operator so can any one help me here
select t1._id, t1."categoryName", t1.company_id, t1.active from table1 t1
inner join table2 t2 on t1._id <> t2.category_id
inner join table3 t3 on t2 .department_id <> t3 ._id where t3._id = 1
for example:
a collage can have 10 departments , students enrolled to 5 department which is present 1 collage
table1 is dept
table 3 is col
table 2 looks like this:
col_id| dept_id | student_id
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
1 | 4 | 4
1 | 5 | 5
i need to fetch rest of the dept_id which is not present in table 2
i need to fetch the table1 content which is not present in the table2
Use a not exists query, something like this:
select *
from table1 t1
where not exists (select *
from table2 t2
where t1._id = t2.category_id)
Note sure how table3 relates to the question "not present in table2"
try not in, or outer join, like here:
select t1._id, t1."categoryName", t1.company_id, t1.active
from table1 t1
left outer join table2 t2 on t1._id = t2.category_id
left outer join table3 t3 on t2 .department_id = t3 ._id
where t3._id = 1
and t2.category_id is null
and t3 ._id is null
yep i got a solution to my question from dbastackexchange this might help others so pasting here
select
cat._id,
cat.cat_name
from
cat
where
not exists(
select
*
from
deptcat
inner join dept on(
dept._id = deptcat.dept_id
)
where
deptcat.cat_id = cat._id
and dept._id = 1
)

Postgres how to maintain order of rows using CTEs

I have 2 tables
students:
id | name | age
1 abc 20
2 xyz 21
scores:
id | studentid | marks
1 1 20
2 2 22
3 2 20
4 1 22
5 1 20
where studentid is foreign key to students table
When a do
select studentid
from scores
where marks=20;
I get the following result
1, 2, 1
But if want the name of the student name and when I do a join using
select t1.name
from students t1
inner join scores t2 on t1.id = t2.studentid
where t2.marks=20;
I get xyz,abc,abc Though the ouput is correct is there any way I can maintain the order in which scores are listed in the scores table? I should get abc,xyz,abc as output. I tried using subquery as well
SELECT name
FROM students
WHERE ID IN ( select studentid from scores where marks=20) ;
but that also did not give me correct order. How can this be achieved using CTEs (common table expressions)? I tried the follownig cte but it did not work
with cte as(
select t2.id, t1.name
from students t1
inner join scores t2 on t1.id = t2.studentid
where t2.marks=20)
select name from cte order by id
You can order by a column not present in select list:
select t1.name
from students t1
inner join scores t2 on t1.id = t2.student_id
where t2.marks=20
order by t2.id;
name
------
abc
xyz
abc
(3 rows)

T-SQL: Selecting column from an alternate table when null

I have the following table, TableA, with data:
ID ColA
0 10
1 null
2 20
I have another table, TableB, with the following data.
ID ColB ColC
1 30 80
1 40 70
3 50 100
I need to select rows in TableA but when ColA in the row is null, I want to retrieve the value of ColB in TableB (if one exists) and use it in place of ColA. If no value in ColB exists, then the value of ColA in the result should be null. The join is done on TableA.ID and TableB.ID. TableB can have multiple rows where the ID column repeats. TableB.ID and TableB.ColC together make a row unique. So my result should look like this if ColC is limited to the value of 70:
ID ColA
0 10
1 40
2 20
Not sure how to do this. Thanks for your help!
select a.ID, COALESCE(a.ColA, b.ColB) as 'ColA'
from TableA a
left join TableB b on a.ID = b.ID and b.ColC = 70
This seems to do what you want if I have correctly interpreted your question:
SELECT a.ID,
ISNULL(a.ColA, b.ColB) ColA
FROM TableA a
LEFT JOIN
TableB b
ON a.ID = b.ID
AND b.ColC = 70
I have literally "limited to the value of 70" in ColC as you stated.
sounds like you're looking for a case statement. try case when TableA.Value is null then TableB.Value end
SQL Case Statements

DB2 query group by id but with max of date and max of sequence

My table is like
ID FName LName Date(mm/dd/yy) Sequence Value
101 A B 1/10/2010 1 10
101 A B 1/10/2010 2 20
101 X Y 1/2/2010 1 15
101 Z X 1/3/2010 5 10
102 A B 1/10/2010 2 10
102 X Y 1/2/2010 1 15
102 Z X 1/3/2010 5 10
I need a query that should return 2 records
101 A B 1/10/2010 2 20
102 A B 1/10/2010 2 10
that is max of date and max of sequence group by id.
Could anyone assist on this.
-----------------------
-- get me my rows...
-----------------------
select * from myTable t
-----------------------
-- limiting them...
-----------------------
inner join
----------------------------------
-- ...by joining to a subselection
----------------------------------
(select m.id, m.date, max(m.sequence) as max_seq from myTable m inner join
----------------------------------------------------
-- first group on id and date to get max-date-per-id
----------------------------------------------------
(select id, max(date) as date from myTable group by id) y
on m.id = y.id and m.date = y.date
group by id) x
on t.id = x.id
and t.sequence = x.max_seq
Would be a simple solution, which does not take account of ties, nor of rows where sequence is NULL.
EDIT: I've added an extra group to first select max-date-per-id, and then join on this to get max-sequence-per-max-date-per-id before joining to the main table to get all columns.
I have considered your table name as employee..
check the below thing helped you.
select * from employee emp1
join (select Id, max(Date) as dat, max(sequence) as seq from employee group by id) emp2
on emp1.id = emp2.id and emp1.sequence = emp2.seq and emp1.date = emp2.dat
I'm a fan of using the WITH clause in SELECT statements to organize the different steps. I find that it makes the code easier to read.
WITH max_date(max_date)
AS (
SELECT MAX(Date)
FROM my_table
),
max_seq(max_seq)
AS (
SELECT MAX(Sequence)
FROM my_table
WHERE Date = (SELECT md.max_date FROM max_date md)
)
SELECT *
FROM my_table
WHERE Date = (SELECT md.max_date FROM max_date md)
AND Sequence = (SELECT ms.max_seq FROM max_seq ms);
You should be able to optimize this further as needed.