Distinct Rows In Sql - 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

Related

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

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;

Get max date based on another column in SQL

I have a table variable which consists of columns id, date and status as shown below
DECLARE #DateValues TABLE (
id int identity(1,1),
dates datetime,
status varchar (5)
)
And follows is the sample data
INSERT INTO #DateValues values ('5/22/2021','')
INSERT INTO #DateValues values ('5/21/2021','ABC')
INSERT INTO #DateValues values ('5/22/2021','ABC')
Also declared a variable as shown below.
DECLARE #MaxID INT
From this table I need to get the row which containing the maximum value of date( MAX(dates) ) where status is 'ABC', from the above sample values, I should get the 3rd row as the result and I need to assign the corresponding id value of the row id to a variable (#MaxID).
I tried following queries but getting multiple result set
SELECT id, MAX(dates), Footer
FROM #DateValues
WHERE STATUS = 'ABC'
GROUP BY id, STATUS
SELECT id, dates, status
FROM #DateValues
WHERE dates = (
SELECT MAX(dates)
FROM #DateValues
);
I need something like:
#MaxID = id
FROM #DateValues
WHERE dates = (
SELECT MAX(dates)
FROM #DateValues
WHERE STATUS='ABC'
);
Please help.
Is this what you want?
SELECT *
FROM (
SELECT *, RN = ROW_NUMBER() OVER (ORDER BY dates DESC)
FROM #DateValues
WHERE status = 'ABC'
) AS D
WHERE D.RN = 1

How can I order data and add a record to the first position of the data set?

I know I can create a temp table, insert records, order it and then use union afterwards, but I'm looking for alternative routes. I tried a cte, but I had to order the entire thing which doesn't work as my unioned record doesn't stay "on top".
Basically, I have at able with Id INT, Name VARCHAR(MAX) fields and I want to ORDER BY Name before I add an entry at the row[0] position in the return set. If I order after the union, the row I wanted at row[0] gets ordered with it.
Any ideas?
You were on the right track with a union query. Force the sort with static values.
select 0 sortfield, '' name, etc
union
select 1 sortfield, name, etc
from etc
order by sortfield, name.
CREATE TABLE #temp (
idnt INT IDENTITY(2) NOT NULL --This begins the identity col with a value of 2
,Id INT
,Name VARCHAR(MAX)
)
INSERT INTO #temp
SELECT
...
FROM myTable
ORDER BY Name
CREATE TABLE #tempAPPEND (
idnt INT IDENTITY(1) NOT NULL --This begins the identity col with a value of 1
,Id INT
,Name VARCHAR(MAX)
)
INSERT INTO #tempAPPEND (Id, Name)
VALUES ('34384','Pinal Dave') -- SAMPLE VALUES
SELECT * FROM #temp
UNION
SELECT * FROM #tempAPPEND
ORDER BY idnt

Update: subquery returned more than 1 value

I am having a problem, and I can't figure out how to fix this query. I have a temp table, one of the columns should contain a calculated value of another column divided by a sum of groups of that column. I don't know how to write this so that I avoid the error.
Declare #Temp Table
(
ZipCode char(5) Not Null,
StateFacilityId varchar (50) Not Null,
Cnt int Not Null,
MarketShare float,
Row int Not Null,
Primary Key Clustered (ZipCode, StateFacilityId)
);
Insert Into #Temp (ZipCode, StateFacilityId, Cnt, Row)
Select d.ZipCode, d.StateFacilityId, Cnt = COUNT(*), Row = ROW_NUMBER()OVER(PARTITION BY ZipCode ORDER BY Count(*) DESC)
From [MarketShareIQData].[dbo].[tblServicesDetail] d
Group By d.ZipCode, d.StateFacilityId
;
Update #Temp
Set MarketShare =(h.Cnt/(
Select SUM(h.Cnt)
From #Temp h
Group By ZipCode
))
From #Temp h
A group by would return one row per group. I'm guessing you're looking for the single group with matching zipcode. You could do that like:
update h
set MarketShare = h.Cnt /
(
select sum(h2.Cnt)
from #Temp h2
where h2.ZipCode = h.ZipCode
)
from #Temp h

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.