Hi,
i have a sample table:
table
ID flag name
1 0 test1
1 0 test2
1 1 test3
2 0 test4
2 0 test5
3 1 test6
4 1 test7
4 1 test8
i would like to have a query that can have a result:
if same id and have both flag = 0 and 1 then only show row with flag =0
if same id and have all flag of 0 then show all the row with flag 0
if id only have flag of 1 then show that row or rows.
Query result:
ID flag name
1 0 test1
1 0 test2
2 0 test4
2 0 test5
3 1 test6
4 1 test7
4 1 test8
Please advised.
Thanks
Ddee
Thanks to ChatGPT for creating the temp table
DROP TABLE if exists #TempTable;
go
CREATE TABLE #TempTable
(
ID INT,
flag int,
name NVARCHAR(50)
);
-- Insert data into the temporary table
INSERT INTO #TempTable (ID, flag, name)
VALUES
(1, 0, 'test1'),
(1, 0, 'test2'),
(1, 1, 'test3'),
(2, 0, 'test4'),
(2, 0, 'test5'),
(3, 1, 'test6'),
(4, 1, 'test7'),
(4, 1, 'test8');
select *
from #TempTable t
where t.flag=0
or
(t.flag=1
and not exists (select 1
from #TempTable tt
where tt.ID=t.ID
and tt.flag=0));
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
July 24, 2023 at 6:58 am
You can get it via this SQL code:
SELECT t.ID, t.flag, t.name
FROM your_table_name t
WHERE
(t.flag = 0 AND NOT EXISTS (
SELECT 1 FROM your_table_name
WHERE ID = t.ID AND flag = 1
))
OR
(t.flag = 0 AND NOT EXISTS (
SELECT 1 FROM your_table_name
WHERE ID = t.ID AND flag = 1
))
OR
-- Show rows with flag = 1 when ID only has flag = 1
(t.flag = 1 AND NOT EXISTS (
SELECT 1 FROM your_table_name
WHERE ID = t.ID AND flag = 0
));
Replace 'your_table_name' with the actual name of your table.
I hope this will work!!
July 25, 2023 at 4:04 am
You can get it via this SQL code:
SELECT t.ID, t.flag, t.name
FROM your_table_name t
WHERE
(t.flag = 0 AND NOT EXISTS (
SELECT 1 FROM your_table_name
WHERE ID = t.ID AND flag = 1
))
OR
(t.flag = 0 AND NOT EXISTS (
SELECT 1 FROM your_table_name
WHERE ID = t.ID AND flag = 1
))
OR
-- Show rows with flag = 1 when ID only has flag = 1
(t.flag = 1 AND NOT EXISTS (
SELECT 1 FROM your_table_name
WHERE ID = t.ID AND flag = 0
));Replace 'your_table_name' with the actual name of your table.
I hope this will work!!
You might want to have a second look... The OR's will very likely be a performance killer and cause heavy resource usage.
Your code also returns an incorrect answer for the given test data...
--Jeff Moden
Change is inevitable... Change for the better is not.
July 25, 2023 at 4:05 am
Thanks to ChatGPT for creating the temp table
Let's see what the actual prompt for that was, please.
For those interested, here's a link to the prompt that I used and the code it produced. There's really no excuse for people to not create test data either when they post of if they decide to try to solve someone's problem that hasn't done such I thing.
https://chat.openai.com/share/166b76be-aa16-4bed-b3b0-b18f0ff41b15
--Jeff Moden
Change is inevitable... Change for the better is not.
July 25, 2023 at 4:40 am
Thanks to ChatGPT for creating the temp table
DROP TABLE if exists #TempTable;
go
CREATE TABLE #TempTable
(
ID INT,
flag int,
name NVARCHAR(50)
);
-- Insert data into the temporary table
INSERT INTO #TempTable (ID, flag, name)
VALUES
(1, 0, 'test1'),
(1, 0, 'test2'),
(1, 1, 'test3'),
(2, 0, 'test4'),
(2, 0, 'test5'),
(3, 1, 'test6'),
(4, 1, 'test7'),
(4, 1, 'test8');
select *
from #TempTable t
where t.flag=0
or
(t.flag=1
and not exists (select 1
from #TempTable tt
where tt.ID=t.ID
and tt.flag=0));
It would be interesting to see how this operates on a much larger table with some decent indexing. On this small of a table, the execution plan has a node that reads 25 rows to output 1 row. Hopefully and as it frequently happens, the optimizer would make a better choice in the plan especially in the presence of some indexes on larger data.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 26, 2023 at 4:37 pm
Hi Ddee,
You can achieve the desired result using the following SQL query:
sql
SELECT ID, flag, name
FROM your_table t
WHERE (flag = 0 AND NOT EXISTS (SELECT 1 FROM your_table WHERE ID = t.ID AND flag = 1))
OR (flag = 1 AND EXISTS (SELECT 1 FROM your_table WHERE ID = t.ID AND flag = 0))
OR flag = 1;
Replace your_table with the actual name of your table. This query will give you the expected output as mentioned in your query result. Let me know if you have question. Thanks
Thanks
Ellen Litwack
SQL Assignment Helper at Buddy Assignment Help
July 26, 2023 at 5:24 pm
Hi, Ellen. Welcome aboard.
It'll be interesting to see how the ORs in that affect performance on larger tables. I'll try to setup a larger test tonight.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 27, 2023 at 1:17 pm
Here is an alternative that a) does not use an OR
and b) does not use a subquery.
WITH TempOrdered AS
(
SELECT t.ID
, t.flag
, t.name
, DENSE_RANK() OVER(PARTITION BY t.ID ORDER BY t.flag) AS dr
FROM #TempTable AS t
)
SELECT t.ID
, t.flag
, t.name
FROM TempOrdered AS t
WHERE t.dr = 1
Drew
J. Drew Allen
Business Intelligence Analyst
Philadelphia, PA
July 27, 2023 at 2:53 pm
Hi Ddee,
You can achieve the desired result using the following SQL query:
sql
SELECT ID, flag, name FROM your_table t WHERE (flag = 0 AND NOT EXISTS (SELECT 1 FROM your_table WHERE ID = t.ID AND flag = 1)) OR (flag = 1 AND EXISTS (SELECT 1 FROM your_table WHERE ID = t.ID AND flag = 0)) OR flag = 1;
Replace your_table with the actual name of your table. This query will give you the expected output as mentioned in your query result. Let me know if you have question. Thanks
Tested this... It returns an incorrect result set and it has the same resource issues as all the other proposed solutions above.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 27, 2023 at 3:00 pm
Here is an alternative that a) does not use an
OR
and b) does not use a subquery.WITH TempOrdered AS
(
SELECT t.ID
, t.flag
, t.name
, DENSE_RANK() OVER(PARTITION BY t.ID ORDER BY t.flag) AS dr
FROM #TempTable AS t
)
SELECT t.ID
, t.flag
, t.name
FROM TempOrdered AS t
WHERE t.dr = 1Drew
+1000000 Drew! This bit of simplicity returns the correct result set, does only the required single scan, and wins in all cases. Even indexes didn't help the others.
The internet is full of "Master SQL" and "Advanced SQL" classes. Those titles are click bait and people, who unfortunately don't know any different, complete the courses, think they've "mastered" advanced SQL, go to an interview, and then wonder why they weren't chosen for the job. Ladies and Gentlemen, the simple analysis that Drew did and then materialized as code is a good example of the reason why. 😉
--Jeff Moden
Change is inevitable... Change for the better is not.
July 27, 2023 at 3:05 pm
For anyone that wants to do a little analysis as to why the use of OR is so bad and to do a little performance testing, here's code to build a million row test example.
--=====================================================================================================================
-- Create the test table and load it with data
--=====================================================================================================================
DROP TABLE IF EXISTS #TestTable;
GO
--===== Create the test table. No indexes were provided in original problem.
CREATE TABLE #TestTable
(
ID INT
,Flag BIT
,Name VARCHAR(50)
)
;
--===== Large data set for performance testing
-- Randomly produces 1 to 4 rows for each ID with random flags of 0 or 1
-- Name is generated by ROW_NUMBER() and is UNIQUE for each row.
DECLARE @Rows INT = POWER(10,6);
INSERT INTO #TestTable WITH (TABLOCK)
(ID, Flag, Name)
SELECT TOP (@Rows)
ID = t.value
,Flag = r2.Flag
,Name = CONCAT('Test',RIGHT('0000000'+CONVERT(VARCHAR(10),ROW_NUMBER() OVER (ORDER BY t.value)),7))
FROM GENERATE_SERIES(1,CONVERT(INT,@Rows/2.4)) t
CROSS APPLY (SELECT value FROM GENERATE_SERIES(1,ABS(CHECKSUM(NEWID())%4)+1))r4(DupeCount)
CROSS APPLY (SELECT ABS(CHECKSUM(NEWID())%2))r2(Flag)
ORDER BY Name
;
--Jeff Moden
Change is inevitable... Change for the better is not.
July 27, 2023 at 3:09 pm
@steve-2 Collins,
I'm still interested in the ChatGPT prompt that you used to generate the populated test table because it'll help people understand how to use ChatGPT to do such a thing.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 27, 2023 at 5:44 pm
Yes sorry, I didn't save that gpt context. Iirc I posted the question in its entirety and asked for sample data and a solution. The query it came up (which was the same/similar to what Priyanka Chouhan posted above (after my reply)) wasn't what I considered a good one. So I wrote the query above which was accepted as the answer. Once the answer is accepted... My approach in general has been to offer a working solution which is as simple as possible. Imo many times this is a helpful approach given the questioner's level of experience. If performance is a requirement then yes it could be refactored
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
July 27, 2023 at 8:58 pm
DENSE_RANK is the better solution in this case though. Good on Drew it's another interesting one
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
Viewing 15 posts - 1 through 15 (of 22 total)
You must be logged in to reply to this topic. Login to reply