TSQL: Find duplicate values based on two database values - sql

I like to find duplicate entrys based on the same "Article" AND "Warehouse" column. I cant find a solution for an MSSQL-Query to find out the different "Value1" and "Value2" based on the following table:
Article Value1 Value2 Warehouse
123 123 01.01.2021 1
123 456 02.12.2022 1
123 789 05.05.2024 1
123 123 01.01.2021 2
123 123 01.01.2021 3
456 123 01.01.2021 1
456 123 01.01.2021 1
456 123 01.01.2021 1
The result should be:
Article Value1 Value2 Warehouse
123 123 01.01.2021 1
123 456 02.12.2022 1
123 789 05.05.2024 1
EDIT: The Warehouse and Article is always different. In the result I want to the see the same article and warehouse which has different entry's on value1 and value2.
As you can see the article "123" AND Warehouse "1" has different entry´s on the value1 and value2. So I´d like to get them in the result of the SQL-Query.
But the article "456" has the SAME entry's on value1 and value2 for Warehouse 1, so I don´t wan´t them in the result.
Thank you very much for your help!

Use COUNT DISTINCT.
select *
from mytable t1
where exists
(
select null
from mytable t2
where t2.article = t1.article and t2.warehouse = t1.warehouse
having count(distinct value1) > 1 or count(distinct value2) > 1
)
order by article, warehouse, value1, value2;
(This would be more readable with an IN clause in my opinion, but SQL Server doesn't allow IN clauses on tuples like WHERE (article, warehouse) IN (...).)

Use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.article = t.article and
t2.warehouse = t.warehouse and
(t2.value1 <> t.value1 or t2.value2 <> t.value2)
);
It is unclear from your question whether both values have to be different or either value. The above implements either value being different.
For performance, I would recommend an index on (article, warehouse, value1, value2).

Related

SQL Oracle: add column from other table twice but with reference to different tables

I have 3 tables.
One of those tables has a key (unique Number) and out of this table I need a column ("Number-Text") to to be added twice in my output table.
Table1:
BelNo
Plant
ProductNo
123
A
999
234
A
888
345
B
989
456
A
999
Table2:
BelNo
MaterialNo
123
001
234
002
345
001
Table3 (with unique values -> each "No" is unique / no duplicates):
No
Number-Text
001
Wood
002
Metal
888
Chair
999
Bed
What I try to get is following table:
BelNo
Plant
ProductNo
Number-Text
MaterialNo
Number-Text
123
A
999
Bed
001
Wood
234
A
888
Chair
001
Wood
345
B
989
Wardrobe
002
Metal
456
A
999
Bed
001
Wood
My Problem is, that with my current code "Number-Text" shows in both columns always the Text from ProductNo ("Bed", "Chair", ...).
What needs to be done, to get a reference in the second "Number-Text" to the column "MaterialNo"?
Here is my current code:
SELECT
Table1.BelNo,
Table1.Plant,
Table1.ProductNo,
Table3.Number-Text,
Table2.MaterialNo,
Table3.Number-Text
FROM
Table1
LEFT JOIN Table3 ON Table1.ProductNo = Table3.No AND Table3.Language = 'E'
LEFT JOIN Table2 ON Table1.BelNo =Table2.BelNo
WHERE
Table1.Plant = 'A'
Sorry, it is my first post. Hope the problem is clearly defined.
This is where table aliases come in.
To join on a table twice, you give at least the second occurrence an alias. I tend to give both occurrences aliases...
SELECT
Table1.BelNo,
Table1.Plant,
Table1.ProductNo,
product.Number-Text AS product_text,
Table2.MaterialNo,
material.Number-Text AS material_text
FROM
Table1
LEFT JOIN
Table3 product
ON product.No = Table1.ProductNo
AND product.Language = 'E'
LEFT JOIN
Table2
ON Table2.BelNo = Table1.BelNo
LEFT JOIN
Table3 material
ON material.No = Table2.MaterialNo
WHERE
Table1.Plant = 'A'

SQL Select Return Rows If Column Contain Value or Null Value Base on Key Columns

It was a bit difficult to describe my requirements based on the title, however I'll post with a table sample and result expectation.
I have a table (lets call it TBL_K) that looks like this:
KEY1 KEY2 VALUE1 VALUE2
abc 123 NULL NULL
abc 123 9999 1111
abc 123 9999 1111
ghd 123 NULL NULL
ghd 123 NULL NULL
tiy 134 4444 NULL
tiy 134 4444 NULL
hhh 981 NULL NULL
I want my Select statement to return the result in:
KEY1 KEY2 VALUE1 VALUE2
abc 123 9999 1111
ghd 123 NULL NULL
tiy 134 4444 NULL
hhh 981 NULL NULL
I have came up with own solution with creating two sub-tables with a left outer join but I want to see if there are other ways of creating this result.
It seems nearly to use max() :
select key1, key2, max(val1), max(val2)
from TBL_K tk
group by key1, key2;
SELECT
A.KEY1,
A.KEY2,
B.VALUE1,
B.VALUE2
FROM
(
SELECT
Z.KEY1,
Z.KEY2,
TRIM(Z.VALUE1) VALUE1,
TRIM(Z.VALUE2) VALUE2
FROM
TBL_K Z
WHERE
TRIM(Z.VALUE1) IS NULL
GROUP BY
Z.KEY1,
Z.KEY2,
Z.VALUE1,Z.VALUE2) A LEFT OUTER JOIN
(
SELECT
Y.KEY1,
Y.KEY2,
TRIM(Y.VALUE1) VALUE1,
TRIM(Y.VALUE2) VALUE2
FROM
TBL_K Y
WHERE
TRIM(Y.VALUE1) IS NOT NULL
GROUP BY
Y.KEY1,
Y.KEY2,
Y.VALUE1,Y.VALUE2) B
ON
(A.KEY1 = B.KEY1
AND A.KEY2 = B.KEY2)

PostgreSQL 9.5 Insert data on a key with multiple occurences

I have 2 tables which are representing the same type of datas, one is in my DB and the other is coming from my client one's. Both his and my table are having some ID as PRIMARY KEY, but they are absolutely not related.
There is a field (field1) which is common between the two table, but this field is not always UNIQUE. In most cases, there are the same amount of tuples with this field in each table, but it is not necessary the case. Here is an example to illustrate the situation :
My table :
id_mytable field1 field2 id_clients
1 aa1 null null
2 aa1 null null
3 aa1 null null
4 aa2 null null
5 aa2 null null
6 aa3 null null
7 aa4 null null
And the client's table:
id_clients field1 field2
9 aa1 value1
10 aa1 value2
11 aa2 value3
12 aa2 value4
13 aa2 value5
14 aa3 value6
15 aa4 value7
And the result I would like to get, sorted by the field1 :
id_mytable field1 field2 id_clients
1 aa1 value1 9
2 aa1 value2 10
3 aa1 null null
4 aa2 value3 11
5 aa2 value4 12
null aa2 value5 13
6 aa3 value6 14
7 aa4 value7 15
You can notice the values not fulfilled in the result table where it was a difference betwenn my and the client's table, and that a new row was inserted. The idea is to be able to fulfill my table with the field2 and the id_clients. So far I cannot figure out a way to achieve that, my guess is that my relative beginner level makes me miss a DB's concept...
And here is an online sample, with the code proposed by ttallierchio : http://rextester.com/LOLH81061
Thank you very much for your attention.
you want to use a full outer join. the reason for this is you are not sure if data exists in either table so you want to combine and take data if exists in either one. i would just use row number to ensure uniqueness.
SELECT row_number() over(order by mt.field1),
coalesce(mt.field1,c.field1) as field1,
coalesce(mt.field2,c.field2) as field2,
c.id as id_clients
FROM mytable mt
FULL OUTER JOIN clients c
on mt.id = c.id and c.field1 = mt.field1;
You can use full outer join. The trick is calculating the new id:
select coalesce(mt.id,
m.maxid + row_number() over (partition by mt.id order by ct.id)
) as newid
mt.field1, ct.field2, ct.id
from mytable mt full outer join
clienttable ct
on mt.id = ct.id and mt.field1 = ct.field1 cross join
(select max(id) as maxid from mytable) as m;

SQLITE - Updating a single row for each unique column pair

I have really basic knowledge in SQL and this seems like a task that requires a complex query to avoid doing multiple queries in a program loop.
I have a table such as the following with 'filename' as UNIQUE column:
title subtitle filename comment selected
abc 123 f1.txt abc 0
xyz 999 f2.txt bla 0
abc 123 f3.txt ppp 0
poc 232 f4.txt ppp 0
xyz 220 f5.txt ppp 0
xyz 999 f6.txt ppp 0
I need to update the 'selected' column to 1 for only a single row (doesn't matter which) for each unique (title, subtitle) pair. This is how the table should be after the query is processed:
abc 123 f1.txt abc 1
xyz 999 f2.txt bla 1
abc 123 f3.txt ppp 0
poc 232 f4.txt ppp 1
xyz 220 f5.txt ppp 1
xyz 999 f6.txt ppp 0
What is the best way to achieve this?
First, get the IDs of those unique rows:
SELECT MIN(rowid) -- or whatever your primary key is
FROM MyTable
GROUP BY title, subtitle
(It does not matter whether you use MIN or MAX.)
Then update those rows:
UPDATE MyTable
SET selected = 1
WHERE rowid IN (SELECT MIN(rowid)
FROM MyTable
GROUP BY title, subtitle)
In SQLite, I think you can do this:
update table
set selected = 1
where not exists (select 1
from table t2
where t2.name < t.name or (t2.name = t.name and t2.title < t.title)
);

Update a column to the same value based on constraints from other columns

I have a table like this on SQL Server:
code description percentage
123 abc 1
123 oke 0
123 cfd 0
234 kde 2
234 kfc 0
234 kfc 0
How can I update the description of all '0 percentage' records to non-zero percentage record for each code group? e.g. the result I'm after is:
code description percentage
123 abc 1
123 abc 0
123 abc 0
234 kde 2
234 kde 0
234 kde 0
Update T1 set description = T2.Description from YourTable T1
inner join
( select code, description from yourTable group by code, description
where percentage <> 0 ) T2 on T1.Code = T2.Code
where T1.Code = 0
Edited
This consider that each group has only zero on only one another description.
Try
UPDATE Table
SET description=(SELECT TOP 1 description
FROM Table t
WHERE t.code = Table.code AND percentage<>'0')
WHERE percentage='0'