SQL Server query with join from other table - sql

I have two tables:
cicmpy with columns:
ID ItemCode Description SecurityLevel Type debcode
and table AAA2 with column
KLIENCIID
I need select * from cicmpy with data (ID) from KLIID.
I tried this select statement:
SELECT *
FROM dbo.cicmpy
WHERE debcode IN (SELECT KLIENCIID FROM AAA2)
Example:
SELECT *
FROM dbo.AAA2
KLIENCIID
300000
300001
300002
SELECT *
FROM dbo.cicmpy
WHERE dbo.cicmpy.debcode = 300000;
ID
ItemCode
debcode
46
ED8D7F34-88A6-439B-85FC-AC9B1461E547
300000

Schema and insert statements:
CREATE TABLE dbo.AAA2 (KLIENCIID varchar(10));
INSERT INTO dbo.AAA2 VALUES(300000);
INSERT INTO dbo.AAA2 VALUES(300001);
INSERT INTO dbo.AAA2 VALUES(300002);
CREATE TABLE dbo.cicmpy
(
ID int,
ItemCode varchar(200),
debcode varchar(10)
);
INSERT INTO dbo.cicmpy
VALUES (46, 'ED8D7F34-88A6-439B-85FC-AC9B1461E547', 300000);
Select query:
SELECT c.*
FROM dbo.cicmpy c
INNER JOIN AAA2 a ON LTRIM(RTRIM(c.debcode)) = LTRIM(RTRIM(a.KLIENCIID))
Output:
ID
ItemCode
debcode
46
ED8D7F34-88A6-439B-85FC-AC9B1461E547
300000
db<>fiddle here

Related

SQL - Update column for each duplicate in other column

I'm looking for an SQL query to update a column to the same Id for each duplicate in another column and then delete each overwritten row from another table.
For example
I have:
IndustryId ProductId ExternalId
144 3332 13
147 3423 13
148 3532 13
2637 63199 32
121 2789 32
I want:
IndustryId ProductId ExternalId
144 3332 13
147 3332 13
148 3332 13
2637 63199 32
121 63199 32
I also need to record the overwritten ProductId values so that I can delete those rows in another table (3423, 3532, and 2789 should be deleted in the other table). Could be in more than one query if neccesary, that doesnt matter.
What is the best way to achieve this?
That isn't too tough, especially if you break out the steps.
Check this out:
if object_id('tempdb..#myData') is not null
drop table #myData;
create table #myData ( industryid int, productId int, externalId int);
insert into #myData (industryId, productId, externalId)
values (144,3332,13);
insert into #myData (industryId, productId, externalId)
values (147,3423,13);
insert into #myData (industryId, productId, externalId)
values (148,3532,13);
insert into #myData (industryId, productId, externalId)
values (2637,63199,32);
insert into #myData (industryId, productId, externalId)
values (121,2789,32);
--select * from #myData;
-------------------------------------------------
if object_id('tempdb..#IdsToKeep') is not null
drop table #IdsToKeep;
if object_id('tempdb..#badRows') is not null
drop table #badRows;
create table #IdsToKeep (externalId int, productId int);
create table #badRows ( industryId int, productId int, externalId int);
insert into #IdsToKeep
select
externalId, min(productId)
from
#myData
group by
externalId;
--- Capture rows that will be changed ---
insert into #badRows
select
md.industryId, md.productId, md.externalId
from
#myData md
left join #IdsToKeep itk on
md.externalId = itk.externalId
and
md.productId = itk.productId
where
itk.productId IS NULL
;
--- Make the update to the main table ---
update
#myData
set
productId = itk.productId
from
#myData
inner join #IdsToKeep itk on #myData.externalId = itk.externalId
;
----------
select * from #mydata;
select * from #badRows;
declare #table table (IndustryId int, ProductId int, ExternalId int) insert into #table values (144,3332,13), (147,3423,13), (148,3532,13), (2637,63199,32), (121,2789,32)
select * from #table
;with cte (productid, externalid) as (select max(productid), ExternalId from #table group by ExternalId) select t.IndustryId, c.productid, c.externalid from cte c right outer join #table t on c.externalid = t.ExternalId

Select one records from three tables based on latest date

I have a TransactionMaster table in SQL Server 2012 that has unique TransactionID. The same TransactionID wil be availabe in LowTransaction ,MediumTransaction and HighTransaction tables.
For each TransactionID in TransactionMaster, I need to display one StatusMessage. The StatusMessage may come from any of the 3 tables - based on date formulated from CRTDTEC and CRTTIME columns..
What is the best way in SQL Server 2012 to select the StatusMessage corresponding to latest date?
Note: CRTDTEC Format - YYMMDD and CRTTIME Format - HHMMSS
CODE
DECLARE #TransactionMaster TABLE (TransactionID INT)
DECLARE #LowTransaction TABLE (TransactionID INT, StatusMessage VARCHAR(80), CRTDTEC VARCHAR(8), CRTTIME VARCHAR(6))
DECLARE #MediumTransaction TABLE (TransactionID INT, StatusMessage VARCHAR(80), CRTDTEC VARCHAR(8), CRTTIME VARCHAR(6))
DECLARE #HighTransaction TABLE (TransactionID INT, StatusMessage VARCHAR(80), CRTDTEC VARCHAR(8), CRTTIME VARCHAR(6))
INSERT INTO #TransactionMaster VALUES (1)
INSERT INTO #TransactionMaster VALUES (2)
INSERT INTO #TransactionMaster VALUES (3)
INSERT INTO #LowTransaction VALUES (1,'1 Low','20131213','235959')
INSERT INTO #MediumTransaction VALUES (1,'1','20131213','235900')
INSERT INTO #HighTransaction VALUES (1,'1 High','20111213','235959')
INSERT INTO #LowTransaction VALUES (2,'2 Low','20111213','235959')
INSERT INTO #LowTransaction VALUES (3,'3 Low','20111213','235959')
INSERT INTO #MediumTransaction VALUES (3,'3 Medium','20111213','235959')
INSERT INTO #HighTransaction VALUES (3,'3 High','20140101','235959')
Expected Result
(1,'1 Low','20131213','235959')
(2,'2 Low','20111213','235959')
(3,'3 High','20140101','235959')
The simplest way would probably be
WITH TransConsolidated
AS (SELECT *
FROM #LowTransaction
UNION ALL
SELECT *
FROM #MediumTransaction
UNION ALL
SELECT *
FROM #HighTransaction)
SELECT TM.TransactionID,
CA.*
FROM #TransactionMaster TM
CROSS APPLY (SELECT TOP 1 *
FROM TransConsolidated TC
WHERE TC.TransactionID = TM.TransactionID
ORDER BY CRTDTEC DESC,
CRTTIME DESC) CA
Or another possibility (if there is a covering index ordered by TransactionID on all tables) would be to merge join all four tables involved
;WITH CTE
AS (SELECT TM.TransactionID,
MAX(CA.CRTDTEC + CA.CRTTIME + CA.StatusMessage) AS MaxRow
FROM #TransactionMaster TM
LEFT MERGE JOIN #LowTransaction LT
ON LT.TransactionID = TM.TransactionID
LEFT MERGE JOIN #MediumTransaction MT
ON MT.TransactionID = TM.TransactionID
LEFT MERGE JOIN #HighTransaction HT
ON HT.TransactionID = TM.TransactionID
CROSS APPLY (SELECT LT.*
UNION ALL
SELECT MT.*
UNION ALL
SELECT HT.*) CA
GROUP BY TM.TransactionID)
SELECT TransactionID,
SUBSTRING(MaxRow, 1, 8),
SUBSTRING(MaxRow, 9, 6),
SUBSTRING(MaxRow, 16, 80)
FROM CTE
I guess you could do something like this...
SELECT TransactionID, StatusMessage, CRTDTEC, CRTTIME
FROM
(
SELECT *, rn = ROW_NUMBER() OVER (PARTITION BY TransactionID ORDER BY CRTDTEC DESC)
FROM
(
SELECT * FROM #LowTransaction
UNION ALL
SELECT * FROM #MediumTransaction
UNION ALL
SELECT * FROM #HighTransaction
)q
) q2
WHERE rn = 1
Result Set
TransactionID StatusMessage CRTDTEC CRTTIME
1 1 Low 20131213 235959
2 2 Low 20111213 235959
3 3 High 20140101 235959

SQL pivot get products by orderNr

I have 2 tables:
'OrderHeader' with columns OrderNr and OrderContact.
'OrderDetail with columns OrderNr and OrderSerial.
For each ordernr there are max 3 orderserials.
So, what I'm trying to get is a table with columns:
OrderNr
OderContact
OrderSerial1
OrderSerial2
OrderSerial3
I'm now stuck with my pivot
SELECT OrderNr,
OderContact,
[1] as OrderSerial1,
[2] as OrderSerial2,
[3] as OrderSerial3
FROM
(select H.OrderNR as OrderNr,
OrderContact as OderContact,
OrderSerialsNr
from OrderHeader H inner join OrderDetail D on H.OrderNr = D.OrderNr
) AS PivSource
PIVOT
(count(OrderSerialsNr) for OrderSerialsNr in([1],[2],[3])) as pvt
I used the adventureworks DB for this.
USE [AdventureWorks2008R2]
GO
create view [test].[OrderHeader] (OrderNr,OrderContact)
as
SELECT SalesOrderID,
FirstName + ' ' + LastName
FROM Sales.SalesOrderHeader INNER JOIN
Sales.Customer ON Sales.SalesOrderHeader.CustomerID = Sales.Customer.CustomerID INNER JOIN
Person.Person ON Sales.Customer.PersonID = Person.Person.BusinessEntityID
GO
CREATE view [test].[OrderDetail] (OrderNr,OrderSerialsNr,Price)
as
SELECT [SalesOrderID]
,[ProductID]
,[unitPrice]
FROM [AdventureWorks2008R2].[Sales].[SalesOrderDetail]
where SalesOrderID in (select SalesOrderID
from [AdventureWorks2008R2].[Sales].[SalesOrderDetail]
group by SalesOrderID
having COUNT(SalesOrderID) < 4)
GO
Please help cause I don't know where to look anymore :).
To get data in pivot table the in claus should have correct data from table
you can get more idea from this query
if 1 and 2 are not in your table it will not appear as count and at a column value
CREATE TABLE #OrderHeader
(ORDERNR INT,
ORDERCONTACT CHAR(5))
CREATE TABLE #ORDERDETAIL
(ORDERNR INT,
ORDERSERIAL VARCHAR(10)
)
INSERT INTO #OrderHeader VALUES ( 1, 'X')
INSERT INTO #ORDERDETAIL VALUES ( 1, 'X1')
INSERT INTO #ORDERDETAIL VALUES ( 1, 'X2')
INSERT INTO #ORDERDETAIL VALUES ( 1, 1)
INSERT INTO #ORDERDETAIL VALUES ( 1, 2)
SELECT * FROM #OrderHeader
SELECT * FROM #ORDERDETAIL
SELECT OrderNr,
OderContact,
[1] as OrderSerial1,
[2] as OrderSerial2,
[3] as OrderSerial3
FROM
(select H.OrderNR as OrderNr,
OrderContact as OderContact,
ORDERSERIAL
from #OrderHeader H inner join #ORDERDETAIL D on H.OrderNr = D.OrderNr
) AS PivSource
PIVOT
(count(ORDERSERIAL) for ORDERSERIAL in([1],[2],[3])) as pvt
DROP TABLE #OrderHeader
DROP TABLE #ORDERDETAIL

"Distinct" column in SQL query

SELECT id, EmpNo
FROM EmployeesTable
EmpNo can be the same for 1 or more records in the results of the above query. I now want to add another column derived from EmpNo(lets call it EmpNo2) but only returning distinct values of EmpNo.
For example if the above query returns 100 records but there are 69 distinct EmpNo values and i modify the query to
SELECT id, EmpNo, Distinct EmpNo2
FROM EmployeesTable EmpNo
,
i want all the 100 rows to be returned but the last column EmpNo2 should return 69 distinct values of EmpNo field.
But as already know, using distinct in that way results into an error but i want to implement such functionality - and a subquery is not helping.
SAMPLE REQUIRED RESULTS
ID EmpNo EmpNo2
1 0T4/HR 0T4/HR
1 0T4/HR 2VP/E
1 0T4/HR xT9/67
1 0T4/HR
1 0T4/HR
2 2VP/E
2 2VP/E
2 2VP/E
2 2VP/E
2 2VP/E
3 XT9/67
3 XT9/67
3 xT9/67
3 XT9/67
How about:
Select id, empno, empno2
from employeestable left outer join (
SELECT min([id]) as minid
,[empno] empno2
FROM [EmployeesTable]
group by empno) etab2 on employeestable.id = etab2.minid
You're saying a subquery won't work, though - why not?
Your requirement is not clear and I also have very little information. Following is what you need. This can be even better but it is just a try.
declare #temp table
(
uniqueid int identity(1, 1),
id int,
empno varchar(50),
empno2 varchar(50)
)
insert into #temp select 1, '0T4/HR', null
insert into #temp select 1, '0T4/HR' , null
insert into #temp select 1 , '0T4/HR' , null
insert into #temp select 1, '0T4/HR' , null
insert into #temp select 1, '0T4/HR' , null
insert into #temp select 2, '2VP/E' , null
insert into #temp select 2, '2VP/E' , null
insert into #temp select 2, '2VP/E' , null
insert into #temp select 2, '2VP/E' , null
insert into #temp select 2, '2VP/E' , null
insert into #temp select 3, 'XT9/67' , null
insert into #temp select 3, 'XT9/67' , null
insert into #temp select 3, 'xT9/67' , null
insert into #temp select 3, 'XT9/67' , null
SELECT ROW_NUMBER() OVER (ORDER BY id) AS id, empno into #temp FROM #temp group by empno, id
update #temp set empno2 = t2.empno
from #temp t inner join #temp t2 on t.uniqueid = t2.id
select * from #temp
drop table #temp

TSQL- generate a sequence number for duplicate records

Using SQL Server 2000, consider a source table with more than 400,000 records.
The task is to select each regno entry with an incrementing on-the-fly rowid or sequence number for those with duplicates or multiple entries. For those which do NOT have duplicate entries in the source table, the rowid should simply be null.
Here's an example of the desired output:
regno rowid
100 1
100 2
100 3
200 null
300 4
300 5
400 null
500 null
600 6
600 7
Question:
What query would do the desired sequence incrementing using TSQL in SQL Server 2000?
If my comment is correct (600 should be 6,7) then have a look at this
DECLARE #Table TABLE(
regno INT,
rowid INT
)
INSERT INTO #Table (regno,rowid) SELECT 100, NULL
INSERT INTO #Table (regno,rowid) SELECT 100, NULL
INSERT INTO #Table (regno,rowid) SELECT 100, NULL
INSERT INTO #Table (regno,rowid) SELECT 200, NULL
INSERT INTO #Table (regno,rowid) SELECT 300, NULL
INSERT INTO #Table (regno,rowid) SELECT 300, NULL
INSERT INTO #Table (regno,rowid) SELECT 400, NULL
INSERT INTO #Table (regno,rowid) SELECT 500, NULL
INSERT INTO #Table (regno,rowid) SELECT 600, NULL
INSERT INTO #Table (regno,rowid) SELECT 600, NULL
DECLARE #TempTable TABLE(
ID INT IDENTITY(1,1),
regno INT
)
INSERT INTO #TempTable (regno)
SELECT regno
FROM #Table
SELECT regno,
CASE
WHEN (SELECT COUNT(1) FROM #TempTable WHERE regno = t.regno) = 1
THEN NULL
ELSE (SELECT COUNT(1) FROM #TempTable WHERE regno = t.regno) - (SELECT COUNT(1) FROM #TempTable WHERE regno = t.regno AND ID > t.ID) +
(SELECT COUNT(1) FROM #TempTable WHERE regno < t.regno AND regno IN (SELECT regno FROM #TempTable GROUP BY regno having COUNT(1) > 1))
END Val
FROM #TempTable t
The query to extract the non-unique records would be
select regno,count(*) from table group by regno having count(*) > 1
I don't know enough about MSSQL to tell you how to generate an incrementing sequence number to update the records that match the query.
Without a temp table:
DECLARE #Table TABLE(
regno INT
)
INSERT INTO #Table (regno) SELECT 100
INSERT INTO #Table (regno) SELECT 100
INSERT INTO #Table (regno) SELECT 100
INSERT INTO #Table (regno) SELECT 200
INSERT INTO #Table (regno) SELECT 300
INSERT INTO #Table (regno) SELECT 300
INSERT INTO #Table (regno) SELECT 400
INSERT INTO #Table (regno) SELECT 500
INSERT INTO #Table (regno) SELECT 600
INSERT INTO #Table (regno) SELECT 600
select regno, null as rowid from #Table group by regno having count(*) = 1
union
select regno, row_number() OVER (ORDER BY a.regno) as rowid
from #table a
where regno in (select regno from #table group by regno having count(*) > 1)
regno rowid
----------- --------------------
100 1
100 2
100 3
200 NULL
300 4
300 5
400 NULL
500 NULL
600 6
600 7
Oops - did not see that you want to do this in SQL 2000 until after posting this ... ignore my query please. In SQL 2000 you need a temp table to generate the sequence.