Find if two columns exist in another table, matched as a pair - sql

I've seen some other questions about comparing multiple columns, but I'm not sure they fit this exact need.
I'm trying to ensure an exact pair of columns in one table exists as the exact same pair of columns in another table. The goal is to check and mark a bit column as true false if it exists.
The last part of this script returns a 1, but I'm not sure if the logic ensures the exact pair is in the second table.
Is the logic in the last part of the script comparing both tables correct?
Sample Data:
CREATE TABLE #t1
(
courseid VARCHAR(10)
,courseNumber VARCHAR(10)
)
INSERT INTO #t1(
courseid
, courseNumber
)
VALUES
(3386341, 3387691)
CREATE TABLE #t2
(
courseid VARCHAR(10)
,courseNumber VARCHAR(10)
,CourseArea VARCHAR(10)
,CourseCert VARCHAR(10)
,OtherCourseNum VARCHAR(10)
)
INSERT INTO #t2(
courseid
, courseNumber
, CourseArea
, CourseCert
, OtherCourseNum
)
VALUES
(3386341 , 3387691 , 9671 , 9671 , 233321)
,(3386341 , 3387691 , 9671 , 9671 , 233321)
,(3386342 , 3387692 , 9672 , 9672 , 233322)
,(3386342 , 3387692 , 9672 , 9672 , 233322)
,(3386343 , 3387693 , 9673 , 9673 , 233323)
,(3386343 , 3387693 , 9673 , 9673 , 233323)
SELECT
CASE WHEN courseid IN (SELECT courseid FROM #t1) AND courseNumber IN (SELECT courseNumber FROM #t2) THEN 1 ELSE 0 END AS IsCourse
FROM #t1

I would always opt for an exists correlation here as it's faster and NULL-safe
select
case when exists (
select * from #t2 t2
where t2.courseid = t1.courseId and t2.courseNumber = t1.courseNumber
) then 1 else 0 end IsCourse
from #t1 t1;

No, your query doesn't correlate the id & number so your query will return a positive if the id exists anywhere in t2 and the number exists anywhere in t2, but doesn't confirm they exist on the same row. You want EXISTS e.g.
SELECT
CASE WHEN EXISTS (
SELECT 1
FROM #t2 t2
WHERE t2.courseid = t1.courseid
AND t2.courseNumber = t1.courseNumber
) THEN 1 ELSE 0 END AS IsCourse
FROM #t1 t1;

Related

Is there any way I could use Alternate for Lead() and Lag() Functions in SQL Server 2008?

I've table where I need to calculate difference between row to one underneath it and get the resultant to xml. it's daily task so i need it is kind of recursive task.
Structure for my current table is as below :
CREATE TABLE #Temp
(
, CurrentDateTime DateTime
, ID INT
, ThisYearToDateTotal INT
, ThisYearToDateCBT INT
, ThisYearToDateManual INT
, ThisYearToDateScanned INT
, InProcess INT
, InputRequired INT
)`
So far I've written the code as below :
SELECT
Today_CurrentDateTime
, Today_Total
, Today_CBT
, Today_Manual
, Today_Scanned
, Today_InProcess
, Today_InputRequired
, Yesterday_Total
, Yesterday_CBT
, Yesterday_Manual
, Yesterday_Scanned
, Yesterday_InProcess
, Yesterday_InputRequired
, (TD.Today_Total - YD.Yesterday_Total) AS Diff_in_Total
, (TD.Today_CBT - YD.Yesterday_CBT) AS Diff_in_CBT
, (TD.Today_Manual - YD.Yesterday_Manual) AS Diff_in_Manual
, (TD.Today_Scanned - YD.Yesterday_Scanned) AS Diff_in_Scanned
, (TD.Today_InProcess - YD.Yesterday_InProcess) AS Diff_in_InProcess
, (TD.Today_InputRequired - YD.Yesterday_InputRequired) AS Diff_in_InputRequired
FROM #YesterdayData AS YD
INNER JOIN #TodayData AS TD ON TD.Today_ID = YD.Yesterday_ID
and getting the output as below :
Now I've a restriction here that I can't create another permanent table and that's why I can't calculate difference for a each day for throughout a week.
Any Help ?
If the dates are input in order of the identity field ID then you can inner join with the same #temp table ON previous ID.
CREATE TABLE #Temp
( CurrentDateTime DateTime
, ID INT
, ThisYearToDateTotal INT
, ThisYearToDateCBT INT
, ThisYearToDateManual INT
, ThisYearToDateScanned INT
, InProcess INT
, InputRequired INT
)
INSERT INTO #Temp VALUES
('2017-11-14 07:50:25.230', 1, 400000, 50000, 20000, 30000, 1000, 700)
,('2017-11-15 07:50:25.230', 2, 460000, 53000, 26000, 38000, 2000, 1400)
,('2017-11-16 07:53:01.943', 3, 469692, 53904, 26755, 389033, 2026, 1489)
,('2017-11-17 07:53:01.943', 4, 469692, 53904, 26755, 389033, 2026, 1489)
DELETE FROM #Temp WHERE ID = 3
SELECT T.CurrentDateTime
, TPrev.ThisYearToDateTotal - T.ThisYearToDateTotal [Total Diff]
, TPrev.ThisYearToDateCBT - T.ThisYearToDateCBT [ThisYearToDateCBT Diff]
, TPrev.ThisYearToDateManual - T.ThisYearToDateManual [ThisYearToDateManual Diff]
, TPrev.ThisYearToDateScanned - T.ThisYearToDateScanned [ThisYearToDateScanned Diff]
, TPrev.InProcess - T.InProcess [InProcess Diff]
, TPrev.InputRequired - T.InputRequired [InputRequired Diff]
FROM #Temp AS T LEFT JOIN #Temp AS TPrev ON TPrev.ID = (SELECT MAX(T2.ID)
FROM #Temp T2
WHERE T2.ID > T.ID)
ORDER BY T.ID
--DROP TABLE #Temp
It's quite easy to mimic LAG and LEAD using sub queries.
For the #Temp table you have in your question, to get ThisYearToDateTotal value of the previous or next row (order by CurrentDateTime).
Here is a simple example:
SELECT ID,
CurrentDateTime,
ThisYearToDateTotal,
(
SELECT TOP 1 ThisYearToDateTotal
FROM #Temp as tLag
WHERE tLag.ID = tMain.Id -- partition by
AND tLag.CurrentDateTime < tMain.CurrentDateTime
ORDER BY CurrentDateTime DESC
) As Lag_ThisYearToDateTotal,
(
SELECT TOP 1 ThisYearToDateTotal
FROM #Temp as tLead
WHERE tLead.ID = tMain.Id -- partition by
AND tLead.CurrentDateTime > tMain.CurrentDateTime
ORDER BY CurrentDateTime
) As Lead_ThisYearToDateTotal
FROM #Temp as tMain

Distinct Rows In Sql

I have a table that record events as it happens and as such could record same ID multiple times. I want to return single row for each unique RefID as 'Y' is substituted for 'N' in relevant columns. Below is a mock-up
DECLARE #Ref TABLE
(
RefID INT
, InvoiceNo INT
, InvoicedDate Date
, CustID INT
, PaidOnTime CHAR(1)
, Paidlate CHAR(1)
, PaidByCash CHAR(1)
, PaidByCard CHAR(1)
)
INSERT INTO #Ref VALUES
(23,50,'22-jun-2015', 11,'Y','N','Y','N')
, (23,50,'22-jun-2015', 11,'Y','N','N','Y')
, (27,11,'12-Aug-2015', 11,'Y','N','N','Y')
, (27,11,'22-Aug-2015', 11,'N','Y','N','Y')
, (45,67,'28-jun-2015', 11,'N','Y','Y','N')
, (45,67,'28-jun-2015', 11,'N','N','N','Y')
, (48,51,'18-jun-2015', 11,'Y','N','Y','N')
SELECT * FROM #Ref --would return values like so:
For example, RefID of 23 should be "23,50,22/06/2015,11,Y,N,Y,Y"
Group by the columns you want to be unique and use max() to get the highest value for every group (since Y is alphabetically higher than N)
SELECT RefID, InvoiceNo, InvoicedDate, CustID,
max(PaidOnTime), max(Paidlate), max(PaidByCash), max(PaidByCard)
FROM #Ref
GROUP BY RefID, InvoiceNo, InvoicedDate, CustID

SQL Server 2008 - Stored inserted IDs in a variable table for another query use later

I have an INSERT query to insert multiple records and returns a set if CompanyID that inserted, and this query is working fine. I would like to stored those returned CompanyIDs into a table variable, so I can run another query after that using those CompanyIDs. I tried, but got stuck.
Please help.
-- Create a table variable
DECLARE #CompanyIDs TABLE
(
CompanyID INT NOT NULL
)
INSERT INTO #CompanyIDs -- STUCK right here and it failed
-- This INSERT query is working fine, and will return the CompanyIDs that inserted.
INSERT INTO [Apps].[dbo].[ERP_Company]
(
[Name]
,[Type]
,[ImportFrom]
,[InActiveFlag]
,[CreatedDate]
,[CreatedBy]
,[CompanyOwnerID]
,[ModifiedDate]
,[HQAddress]
,[HQCity]
,[HQState]
,[HQZip]
,[Type2]
,[Segment]
,[Industry]
)
output inserted.CompanyID
SELECT DISTINCT(Company) AS Company
, 'End-User'
, 'MarketingUpload'
, '0'
, GETDATE()
, '1581'
, '1581'
, GETDATE()
, [Address]
, City
, [State]
, ZipCode
, 'Customer'
, Segment
, Industry
FROM dbo.Import_CompanyContact icc
WHERE RefNum = 14
AND MatchFlag = 3
AND NOT Exists (SELECT * FROM dbo.ERP_Company
WHERE REPLACE(Name, '''', '') = REPLACE(icc.Company, '''', '')
)
OUTPUT inserted.CompanyID INTO #YourTable

ORA 00937 while using INSERT INTO SELECT

When I am running the below insert into select statement, I get ORA 00937 because the below query cannot deal with one of the sub selects on APPLICATIONS table. I don't want to hardcode that value. Any suggestions?
Thanks in advance.
insert into CONFIGURATION_PARAMETER_VALUES
( ID
, NAME
, DESCRIPTION
, DATA_TYPE
, VALUE_STRING
, VALUE_INTEGER
, VALUE_DATE
, VALUE_FLOAT
, VALUE_TIMESTAMP
, APPLICATION_ID
, DELETED
)
select NVL(MAX(ID),0)+1
, 'Alert_Statuses_AllExceptNoStatus'
, 'Suspicious'
, 'String'
, 'RBS_EIM_AL_008'
, null
, null
, null
, null
, (select ID from APPLICATIONS where name = 'Rabobank v 1.0.0.0')
, 'N'
from CONFIGURATION_PARAMETER_VALUES
If it's not too late, I'd suggest implementing a SEQUENCE instead of counting. You may not get strict numeric order (there can be gaps), but you'll get a unique value every time:
CREATE SEQUENCE Config_Parm_Values_Seq START WITH <1 + your current max ID>;
Also note that your INSERT as it stands right now will behave as follows:
If there are no records in the table, it will insert nothing.
If there are records in the table, it will double the number of rows in your table every time you execute it.
So, even if you don't use the sequence, I'd consider a "plain old" INSERT instead of an INSERT ... SELECT. This example uses the sequence:
insert into CONFIGURATION_PARAMETER_VALUES
( ID
, NAME
, DESCRIPTION
, DATA_TYPE
, VALUE_STRING
, VALUE_INTEGER
, VALUE_DATE
, VALUE_FLOAT
, VALUE_TIMESTAMP
, APPLICATION_ID
, DELETED
) VALUES (
Config_Parm_Values_Seq.NEXTVAL -- Use seqname.nextval to get
-- the next value from the sequence
, 'Alert_Statuses_AllExceptNoStatus'
, 'Suspicious'
, 'String'
, 'RBS_EIM_AL_008'
, null
, null
, null
, null
, (select MAX(ID) from APPLICATIONS where name = 'Rabobank v 1.0.0.0')
, 'N')
The problem is in your SELECT statement where you are using SELECT NVL(MAX(ID), 0) + 1.
As you are using MAX function in the SELECT list, you must use a GROUP BY, which is not the solution here.
Use something like the following:
insert into CONFIGURATION_PARAMETER_VALUES
( ID
, NAME
, DESCRIPTION
, DATA_TYPE
, VALUE_STRING
, VALUE_INTEGER
, VALUE_DATE
, VALUE_FLOAT
, VALUE_TIMESTAMP
, APPLICATION_ID
, DELETED
)
select (SELECT MAX(ID) FROM configuration_parameter_values) + 1
-- above line instead of NVL(MAX(ID),0)+1
-- You can also put NVL function around the subquery.
, 'Alert_Statuses_AllExceptNoStatus'
, 'Suspicious'
, 'String'
, 'RBS_EIM_AL_008'
, null
, null
, null
, null
, (select ID from APPLICATIONS where name = 'Rabobank v 1.0.0.0')
-- Warning: The above subquery can generate a TOO_MANY_ROWS exception.
-- Use the solution in the other answer to avoid this.
, 'N'
from CONFIGURATION_PARAMETER_VALUES

sql query serial number

I have written a stored procedure in SQL Server 2000. I want a serial number for output table.
So when I run this stored proc I get this error:
An explicit value for the identity column in table
'#tmpSearchResults1' can only be specified when a column list is used
and IDENTITY_INSERT is ON.
I have tried with set IDENTITY_INSERT #tmpSearchResults1 on
Create Procedure dbo.usp_mobile_All_KeyWord(#searchkey varchar(30))
AS
CREATE TABLE #tmpSearchResults
(
property_id varchar(255),
property_number varchar(255),
auction_date_reason varchar(255)
)
INSERT INTO #tmpSearchResults
SELECT
p.property_id, p.property_number, p.auction_date_reason
FROM
Pr p
INNER JOIN
Au a ON p.auction_id = a.auction_id
INNER JOIN
PrAdd pa ON p.property_id = pa.property_id
INNER JOIN state AS s ON s.state_id=pa.state
where
(
(p.archive = 'N'
AND
a.show_on_site = 'Y'
AND
(
(
((p.auction_date >= CONVERT(datetime, CONVERT(varchar, GETDATE(), 103), 103) and (p.auction_date_reason is null or p.auction_date_reason = ''))
or
(p.auction_date <= CONVERT(datetime, CONVERT(varchar, GETDATE(), 103), 103) and ( p.auction_date_reason = 'Accepting Offers' )))
and
pa.property_address_type_id = 1 )) )
and
(state_abbreviation=#searchkey or s.state_name like '%'+''+ #searchkey +''+'%' or city like '%'+''+ #searchkey +''+'%' or pa.address1 like '%'+''+ #searchkey +''+'%'
or pa.address2 like '%'+''+ #searchkey +''+'%')
)
)
CREATE TABLE #tmpSearchResults1
(
i1 int identity,
property_id varchar(255),
property_number varchar(255),
auction_date_reason varchar(255)
)
insert into #tmpSearchResults1
select
property_id ,
property_number,
auction_date_reason
from #tmpSearchResults
order by
case when charindex(#searchkey,state) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,statename) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,city) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,address2) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,address1) >0 then 1000 else 0 end desc,
case when charindex(#searchkey,short_description) >0 then 1000 else 0 end desc
select * from #tmpSearchResults1
Plz do help me
The error code is very very very clear.
The relevant portion is ...when a column list is used....
You need to specify your column list in the INSERT statement.
INSERT INTO #tmpSearchResults
(i1,
property_id,
property_number,
auction_date_reason)
SELECT
p.property_id, p.property_number, p.auction_date_reason
FROM...
First, there is a comma too much in the SELECT part of your second statement:
insert into #tmpSearchResults1
select
property_id ,
property_number,
auction_date_reason , <-- THIS ONE!!
from #tmpSearchResults
The last column of a SELECT statement must be without a comma.
So this would be correct:
insert into #tmpSearchResults1
select
property_id ,
property_number,
auction_date_reason
from #tmpSearchResults
Second, did you read this part of the error message?
An explicit value [...] can only be specified when a column list is used
The "column list" part means that you have to specify the columns in the INSERT part:
insert into #tmpSearchResults1
(property_id, property_number, auction_date_reason)
select
property_id ,
property_number,
auction_date_reason
from #tmpSearchResults
You can get away with not specifying the columns when the number of columns in the SELECT statement is the same as in the table in which they should be inserted (and if the data types match).
If one of these conditions is not met, you need to specify the columns because otherwise SQL Server doesn't know which value to insert into which column.