Select rows where one column has duplicate values based on another column which contains specific strings - sql

I have a table where in customer number column contains duplicate values and I would like to select all rows where there are duplicate entries for customer number, but only select those rows where WO Type column only contains these specific values ('IMU','Electric') so in the table image attached to this question: I should only get rows for ID 1 and 2.
I do not want those duplicates counted where the pair of duplicate rows also contain GAS, but only want those duplicate rows which exclusively contain only IMU and Electric values in WO Type Column
Your help is much appreciated.

You can use group by and having:
select customerNumber
from t
where woType in ('EMU', 'Electric')
group by customerNumber
having count(*) = 2;
Note: This assumes no duplicates. To handle this, you can use:
having min(woType) <> max(woType)
or:
having count(distinct woType) = 2 -- number of elements in IN list

SELECT *
FROM tbl t1
WHERE EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype = 'IMU'
) AND EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype = 'Electric'
) AND NOT EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype NOT IN ('IMU', 'Electric')
)
Here's a fiddle.

Try this:
select * from Table1 Main
Inner JOIN (
select Customer_Number
From Table1
group by Customer_Number
Having COunt(Customer_Number)>1) SUB ON Main.Customer_Number=SUB.Customer_Number
WHERE Main.Wo_Type IN ('IMU','Electric')
This Query will return the duplicate set or rows in the table.

Related

Select a row of the table with desired value, when a column's value which is not in the table is selected in where clause in keyword?

I have a table with one of the columns as ID. I have a set of values which I give in the where clause to compare the 'ID' column using 'in' keyword. I want to select the row if the value in that set of values has a record in the table. If not, the value that is not in the table has to be selected along with empty values other columns.
For example:
There is a table with columns ID & Animal. It has 8 records.
The table with all records
If I run the query:
SELECT ID, Animal from #Temp1 where ID in (4,8)
it will return the following result.
The table result filtered
But, if I run the query:
SELECT ID, Animal from #Temp1 where ID in (4,8,12)
it should return the following result.
The table result with desired values
Use a LEFT JOIN in concert with string_split() instead
Select ID = A.value
,Animal = coalesce(B.Animal,'ID Not Found')
From string_split('4,8,12',',') A
Left Join YourTable B on A.value=B.ID
Results
ID Animal
4 Donkey
8 Hampster
12 ID Not Found
If by chance string_split() is not available
Select ID = A.value
,Animal = coalesce(B.Animal,'ID Not Found')
From (values (4)
,(8)
,(12)
) A(value)
Left Join YourTable B on A.value=B.ID

How to select only values that are not repeating in a column example if a have column with following values "A,b,c,a,c" i have to select only b

How to select only values that are not repeating in a column? For example if a have table with following values I expect to return only the id value of b:
id
--
a
b
c
a
c
Aggregation provides one approach:
SELECT id
FROM yourTable
GROUP BY id
HAVING COUNT(*) = 1;
In subselecet you select values which have only one record, Than in outer select you search for all datas based on that value in subselect
SELECT *
FROM table
WHERE id IN (SELECT id
FROM table
GROUP BY id
HAVING COUNT (id) = 1)

SQL query to return rows where only one record is present in a given status

I have a table with data similar to below. I am trying to get a list of results that will display all rows where only one unique SourceID exists in status 10. If I were querying this table, I would expect ID's 3 and 4 to be returned.
Table Example
Select *
From table
Where Status = 10 and Source ID in
(
Select SourceID
From Table
Group by SourceID
Having Count(*) = 1
)
You can use NOT EXISTS :
SELECT t.*
FROM table t
WHERE NOT EXISTS (SELECT 1 FROM table t1 WHERE t1.SourceID = t.SourceID AND t1.Status <> t.Status);
Maybe that would work?
SELECT ID FROM Mytable
WHERE [Status] = 10
GROUP BY ID
HAVING COUNT(SourceID) = 1
First, find out all the unique SourceIDs
SELECT
SourceID
FROM
Data
GROUP BY
SourceID
HAVING
COUNT(SourceID) = 1
And then use this query as a sub query to get all the rows that has unique SourceID;
SELECT
*
FROM
Data
WHERE
SourceID IN (
SELECT
SourceID
FROM
Data
GROUP BY
SourceID
HAVING
COUNT(SourceID) = 1
)
Use a sub-query to check if t there is an exact count of 1 of those source id's
SELECT t.* FROM YourTable t WHERE t.status = 10
AND
(SELECT COUNT(0) x From YourTable t2
where t2.sourceid = t.sourceid) = 1

Merging data of two SQL Server tables with auto Increment

Using SQL Server, I have two tables that I want to merge. Table2 has a tbID column that has NULL values. I would like for NULL values to be automatically updated, beginning with the next value of the tbID column, from Table1 when the tables are merged.
I am entering something like this..
SELECT
A.tbID,
A.etID,
A.cNumber,
A.cName
FROM
Table1 AS A
UNION ALL
SELECT
B.tbID,
B.etID,
B.cNumber,
B.cName
FROM
Table2 AS B
My results has a NULL value (instead of an automatically inserted number), in the records from Table2.
If by "merge" you want all the records to end up in table1 - just leave the id column out of the insert:
INSERT INTO table1 (etID, cNumber, cName)
SELECT etID, cNumber, cName
FROM table2
If you just want to select and see incremented ids for the data coming from table2, here is one way:
SELECT A.tbID,
A.etID,
A.cNumber,
A.cName
FROM Table1 AS A
UNION ALL
SELECT (SELECT MAX(tbID) FROM Table1) +
ROW_NUMBER() OVER (ORDER BY B.etID),
B.etID,
B.cNumber,
B.cName
FROM Table2 AS B
If you just want a result set, you can use:
SELECT A.tbID, A.etID, A.cNumber, A.cName
FROM Table1 A
UNION ALL
SELECT (a.maxID + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) as tbID,
B.etID, B.cNumber, B.cName
FROM Table2 B CROSS JOIN
(SELECT MAX(A.tbID) as maxID FROM Table1 as A) a;
If you are inserting these rows into a new table, then the id can be assigned automatically -- but the values might differ for A.

Select DISTINCT, return entire row

I have a table with 10 columns.
I want to return all rows for which Col006 is distinct, but return all columns...
How can I do this?
if column 6 appears like this:
| Column 6 |
| item1 |
| item1 |
| item2 |
| item1 |
I want to return two rows, one of the records with item1 and the other with item2, along with all other columns.
In SQL Server 2005 and above:
;WITH q AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY col6 ORDER BY id) rn
FROM mytable
)
SELECT *
FROM q
WHERE rn = 1
In SQL Server 2000, provided that you have a primary key column:
SELECT mt.*
FROM (
SELECT DISTINCT col6
FROM mytable
) mto
JOIN mytable mt
ON mt.id =
(
SELECT TOP 1 id
FROM mytable mti
WHERE mti.col6 = mto.col6
-- ORDER BY
-- id
-- Uncomment the lines above if the order matters
)
Update:
Check your database version and compatibility level:
SELECT ##VERSION
SELECT COMPATIBILITY_LEVEL
FROM sys.databases
WHERE name = DB_NAME()
The key word "DISTINCT" in SQL has the meaning of "unique value". When applied to a column in a query it will return as many rows from the result set as there are unique, different values for that column. As a consequence it creates a grouped result set, and values of other columns are random unless defined by other functions (such as max, min, average, etc.)
If you meant to say you want to return all rows for which Col006 has a specific value, then use the "where Col006 = value" clause.
If you meant to say you want to return all rows for which Col006 is different from all other values of Col006, then you still need to specify what that value is => see above.
If you want to say that the value of Col006 can only be evaluated once all rows have been retrieved, then use the "having Col006 = value" clause. This has the same effect as the "where" clause, but "where" gets applied when rows are retrieved from the raw tables, whereas "having" is applied once all other calculations have been made (i.e. aggregation functions have been run etc.) and just before the result set is returned to the user.
UPDATE:
After having seen your edit, I have to point out that if you use any of the other suggestions, you will end up with random values in all other 9 columns for the row that contains the value "item1" in Col006, due to the constraint further up in my post.
You can group on Col006 to get the distinct values, but then you have to decide what to do with the multiple records in each group.
You can use aggregates to pick a value from the records. Example:
select Col006, min(Col001), max(Col002)
from TheTable
group by Col006
order by Col006
If you want the values to come from a specific record in each group, you have to identify it somehow. Example of using Col002 to identify the record in each group:
select Col006, Col001, Col002
from TheTable t
inner join (
select Col006, min(Col002)
from TheTable
group by Col006
) x on t.Col006 = x.Col006 and t.Col002 = x.Col002
order by Col006
SELECT *
FROM (SELECT DISTINCT YourDistinctField FROM YourTable) AS A
CROSS APPLY
( SELECT TOP 1 * FROM YourTable B
WHERE B.YourDistinctField = A.YourDistinctField ) AS NewTableName
I tried the answers posted above with no luck... but this does the trick!
select * from yourTable where column6 in (select distinct column6 from yourTable);
SELECT *
FROM harvest
GROUP BY estimated_total;
You can use GROUP BY and MIN() to get more specific result.
Lets say that you have id as the primary_key.
And we want to get all the DISTINCT values for a column lets say estimated_total, And you also need one sample of complete row with each distinct value in SQL. Following query should do the trick.
SELECT *, min(id)
FROM harvest
GROUP BY estimated_total;
create table #temp
(C1 TINYINT,
C2 TINYINT,
C3 TINYINT,
C4 TINYINT,
C5 TINYINT,
C6 TINYINT)
INSERT INTO #temp
SELECT 1,1,1,1,1,6
UNION ALL SELECT 1,1,1,1,1,6
UNION ALL SELECT 3,1,1,1,1,3
UNION ALL SELECT 4,2,1,1,1,6
SELECT * FROM #temp
SELECT *
FROM(
SELECT ROW_NUMBER() OVER (PARTITION BY C6 Order by C1) ID,* FROM #temp
)T
WHERE ID = 1