Compare the values of column in SQL Server - sql-server

Table_1 columns are:
======================
A B
======================
100 4
-----------
101 2
101 3
101 4
-----------
102 6
-----------
103 7
-----------
104 2
104 3
104 4
-----------
105 2
-----------
106 4
-----------
107 3
--------------------------------
Now I have input B parameter like '6' or '2,3,4'.
I want to get a result like this:
if input B parameter is '6', then output should be:
======================
A B
======================
102 6
If input B parameter is '2,3,4', then output should be:
======================
A B
======================
101 2
101 3
101 4
-----------
104 2
104 3
104 4

Just select the needed columns:
SELECT A, B
FROM Table_1
WHERE B IN (2,3,4)
EDIT:
If you need them only if all params are present
SELECT A, B
FROM Table_1
WHERE A IN (SELECT A FROM Table_1 WHERE B = 2) AND A IN (SELECT A FROM Table_1 WHERE B = 3) AND A IN (SELECT A FROM Table_1 WHERE B = 4)

You can try this one, for your specific requirement -
-- the last digit after = i.e. 3 should be replaced by number of inputs in check for our case it is 3 for (2,3,4)
SELECT A,B FROM Table_1 AS tbl1 WHERE B IN (2,3,4) AND (select COUNT(1) FROM Table_1 AS tbl2 WHERE B IN (2,3,4) AND tbl1.A = tbl2.A)
= 3
Please, have a look.
Thanks!

SELECT A
,B
FROM table_1
WHERE A IN (
SELECT A
FROM table_1
WHERE B = 2
)
AND A IN (
SELECT A
FROM table_1
WHERE B = 3
)

Related

SQL Server Join 2 Tables with Relationship in 3rd Table

I have 3 tables:
Table_A
tblA_ID | tblA_Key | tblA_Info
1 2A ABC
Table_B
tblB_ID | tblB_to_A_Relations | tblB_Info
1 1 XYZ
2 1 DEF
3 1 QWE
4 1 NOP
Table_C
tblC_ID | tblC_to_A_Relations | tblC_Info
1 2A 999
2 2A 888
3 2A 777
Table_B and Table_C doesn't have direct relationship but I wanted to join them by using their relationships on Table_A. This is what I've tried so far.
SELECT DISTINCT
b.*,
c.tblC_Info,
FROM Table_B b
LEFT JOIN (SELECT tblA_ID, tblA_Key FROM Table_A
WHERE tblA_Key = #parameter)a
ON a.tblA_ID = b.tblB_to_A_Relations
LEFT JOIN Table_C c
ON c.tblC_to_A_Relations = a.tblA_Key
ORDER BY b.tblB_ID ASC
Somehow outputs:
ResultSet
tblB_ID | tblB_to_A_Relations | tblB_Info | tblC_Info
1 1 XYZ 999
1 1 XYZ 888
1 1 XYZ 777
2 1 DEF 999
2 1 DEF 888
2 1 DEF 777
3 1 QWE 999
3 1 QWE 888
3 1 QWE 777
4 1 NOP 999
4 1 NOP 999
4 1 NOP 999
But my expected output is something like this:
ExpectedOutput
tblB_ID | tblB_to_A_Relations | tblB_Info | tblC_Info
1 1 XYZ NULL
2 1 DEF 999
3 1 QWE 888
4 1 NOP 777
Surely missing something. Any help would really be appreciated!
EDIT
After more inspection of the existing tables and data, it appears that the above results are already filtered records and luckily, after tedious tracing, I found a field that somehow tells them they are unique from the other records.
Table_B
tblB_ID | tblB_to_A_Relations | tblB_Info | **tblB_Values**
1 1 XYZ AAA
2 1 DEF BBB
3 1 QWE CCC
4 1 NOP DDD
Table_C
tblC_ID | tblC_to_A_Relations | tblC_Info | **tblC_Values**
1 2A 999 BBB
2 2A 888 CCC
3 2A 777 DDD
At first, I made a mistake to ignore these fields not knowing the answer was there all along.
Going to post my answer.
Declare #A table
(
tbla_ID int,
tblA_Key varchar(2),
tbla_info varchar(3)
)
Declare #B table
(
tblb_ID int,
tblB_to_A varchar(2),
tblB_info varchar(3)
)
Declare #C table
(
tblb_ID int,
tblC_to_A varchar(2),
tblB_info int
)
Insert into #A
Select 1,'2A','ABC'
Insert into #B
Select 1,1,'XYZ'
union
Select 2,1,'DEF'
union
Select 3,1,'QWE'
union
Select 4,1,'NOP'
Insert into #c
Select 1,'2A',999
UNION
Select 2,'2A',888
UNION
Select 3,'2A',777
Select B.*,C.tblB_info from #A A
join #B B
on A.tbla_ID=B.tblB_to_A
left join #C C
on B.tblb_ID=C.tblb_ID and A.tbla_key=C.tblC_to_A
Null value belongs to 4th row exactly equal to 'NOP'
The workaround I did:
Create a temporary container and update unique keys from Table_B to Table_C in a modified column of a temporary table with reference to Table_A.
Here's what the temporary table looked like:
TempTbl
tblC_ID | Modified_Col | tblC_to_A_Relations | tblC_Info
1 2 2A 999
2 3 2A 888
3 4 2A 777
Managed to get this resultset using a copy of Table_C (#TempTbl)
UPDATE #TempTbl
SET
#TempTbl.Modified_Col = #TempTbl_B.tblB_ID
FROM
#TempTbl
INNER JOIN
#TempTbl_B
ON
#TempTbl.tblB_Values = #TempTbl_B.tblC_Values
And pulled left join for final result.
SELECT * FROM Table_B x
LEFT JOIN #TempTbl y
ON x.tblB_ID = y.Modified_Col
PS: I really do apologize how horrible the workaround was.

SQL Server Job Alerts, find matches from user saved searches

I'm trying to create a script that checks user's 'saved searches' against live jobs.
The desired output would be a table/list of; JobID + JobSearchID.
To approach this I've created a temp table, #TempJobSavedSearches.
SELECT
JS.JobSearchID,
JS.JobSortByOptionID,
Radius,
JobTypeID,
JobSearchKeywordID,
TownCityLookupID,
CountryID,
WorkingHoursID,
SectorID,
SalaryFrom,
SalaryTo
INTO #TempJobSavedSearches
FROM UserJobSearches AS UJS
JOIN JobSearches AS JS ON UJS.JobSearchID = JS.JobSearchID
LEFT JOIN JobSearchJobTypes ON JS.JobSearchID = JobSearchJobTypes.JobSearchID
LEFT JOIN JobSearchStrings ON JS.JobSearchID = JobSearchStrings.JobSearchID
LEFT JOIN JobSearchTowns ON JS.JobSearchID = JobSearchTowns.JobSearchID
LEFT JOIN JobSearchWorkingHours ON JS.JobSearchID = JobSearchWorkingHours.JobSearchID
LEFT JOIN JobSearchCountries ON JS.JobSearchID = JobSearchCountries.JobSearchID
LEFT JOIN JobSearchSectors ON JS.JobSearchID = JobSearchSectors.JobSearchID
LEFT JOIN JobSearchSalaries ON JS.JobSearchID = JobSearchSalaries.JobSearchID
LEFT JOIN JobSortByOptions ON JS.JobSortByOptionID = JobSortByOptions.JobSortByOptionID
WHERE Alert = 1
This creates:
JobSearchID JobSortByOptionID Radius JobTypeID JobSearchKeywordID TownCityLookupID CountryID WorkingHoursID SectorID SalaryFrom SalaryTo
----------- ----------------- ----------- ----------- ------------------ ---------------- ----------- -------------- ----------- ----------- -----------
901 8 200 1 NULL 1 4 2 31 30001 40000
901 8 200 1 NULL 1 4 2 34 30001 40000
904 8 10 1 114 1 4 2 23 30001 40000
904 8 10 1 114 1 4 2 24 30001 40000
904 8 10 1 114 1 4 2 39 30001 40000
I then thought I could loop through each JobSearchID, and compare the respective data to my Jobs table.
Jobs:
JobID TownCityLookupID WorkingHoursID JobTypeID JobTitle JobDescription SalaryFrom SalaryTo
----- ---------------- -------------- --------- -------- -------------- ---------- --------
1 1 2 5 foo foo 10000 60000
2 1 2 1 foo foo 30000 60000
3 11 3 3 bar bar 70000 100000
Other link tables (some tables/columns excluded for brevity);
JobSectors
SectorID JobID
-------- -----
18 1
19 1
20 1
21 1
23 2
24 2
25 2
26 2
44 3
TownCities
TownCityLookupID CountryID
---------------- ---------
1 4
11 8
Here's my loop/attempt and comparing the results;
DECLARE #JobSearchID int = 0
DECLARE #CountryID int = 0
DECLARE #TownCityLookupID int = 0
DECLARE #WorkingHoursID int = 0
DECLARE #SalaryFrom int = 0
DECLARE #SalaryTo int = 0
WHILE(1 = 1)
BEGIN
SELECT #JobSearchID = MIN(JobSearchID)
FROM #TempJobSavedSearches WHERE JobSearchID > #JobSearchID
IF #JobSearchID IS NULL BREAK
-- store single vars
SELECT #CountryID = (SELECT TOP(1) CountryID FROM #TempJobSavedSearches WHERE JobSearchID = #JobSearchID)
SELECT #TownCityLookupID = (SELECT TOP(1) TownCityLookupID FROM #TempJobSavedSearches WHERE JobSearchID = #JobSearchID)
SELECT #WorkingHoursID = (SELECT TOP(1) WorkingHoursID FROM #TempJobSavedSearches WHERE JobSearchID = #JobSearchID)
SELECT #SalaryFrom = (SELECT TOP(1) SalaryFrom FROM #TempJobSavedSearches WHERE JobSearchID = #JobSearchID)
SELECT #SalaryTo = (SELECT TOP(1) SalaryTo FROM #TempJobSavedSearches WHERE JobSearchID = #JobSearchID)
-- should I be joining on jobs not on temp table?
SELECT #JobSearchID, JobID FROM #TempJobSavedSearches
INNER JOIN JobSectors ON #TempJobSavedSearches.SectorID = JobSectors.SectorID
INNER JOIN JobSortByOptions ON #TempJobSavedSearches.JobSortByOptionID = JobSortByOptions.JobSortByOptionID
INNER JOIN JobTypes ON #TempJobSavedSearches.JobTypeID = JobTypes.JobTypeID
INNER JOIN JobSearchKeywords ON #TempJobSavedSearches.JobSearchKeywordID = JobSearchKeywords.JobSearchKeywordID
WHERE
JobSearchID = #JobSearchID
AND CountryID = #CountryID
TownCityLookupID = #TownCityLookupID
AND WorkingHoursID = #WorkingHoursID
AND SalaryFrom < #SalaryTo
AND SalaryTo > #SalaryFrom
END
However its returning both IDs, where I expected only JobID 2 to be shown
JobSearchID JobID
----------- -----
901 1
901 2
901 1
901 2
901 1
901 2
901 1
901 2
901 1
901 2
901 1
901 2
901 1
901 2
901 1
901 2
Could anyone explain what I'm doing wrong. Or provide a link to some reading that could help?

how to select all value from two table

tableA tableB
IdPrice price id tax IdPrice
---------------------- ------------------------------------
4 100 1 20 4
------------------------ ------------------ ------------------
5 150 2 10 6
------------------------ ------------------ ------------------
6 270
------------------------
result =
price id tax
---- --- ----
100 1 20
150 2 10
270 null null
my Query
SELECT price,id,tax
FROM tableB INNER JOIN
tableA ON tableA.IdPrice= tableB.IdPrice
but this result
price id tax
---- --- ----
100 1 20
150 2 10
SELECT
a.price as price, b.id as id, b.tax as tax
FROM
tableA a
LEFT OUTER JOIN
tableB b ON a.IdPrice = b.IdPrice
Use left outer join you can get all the records from tableA.

SQL Query to fill missing gaps across time and get last non-null value

I have the following table in my database:
Month|Year | Value
1 |2013 | 100
4 |2013 | 101
8 |2013 | 102
2 |2014 | 103
4 |2014 | 104
How can I fill in "missing" rows from the data, so that if I query from 2013-03 through 2014-03, I would get:
Month|Year | Value
3 |2013 | 100
4 |2013 | 101
5 |2013 | 101
6 |2013 | 101
7 |2013 | 101
8 |2013 | 102
9 |2013 | 102
10 |2013 | 102
11 |2013 | 102
12 |2013 | 102
1 |2014 | 102
2 |2014 | 103
3 |2014 | 103
As you can see I want to repeat the previous Value for a missing row.
I have created a SQL Fiddle of this solution for you to play with.
Essentially it creates a Work Table #Months and then Cross joins this will all years in your data set. This produces a complete list of all months for all years. I then left join the Test data provided in your example (Table named TEST - see SQL fiddle for schema) back into this list to give me a complete list with Values for the months that have them. The next issue to overcome was using the last months values if this months didn't have any. For that, I used a correlated sub-query i.e. joined tblValues back on itself only where it matched the maximum Rank of a row which has a value. This then gives a complete result set!
If you want to filter by year\month you can add this into a WHERE clause just before the final Order By.
Enjoy!
Test Schema
CREATE TABLE TEST( Month tinyint, Year int, Value int)
INSERT INTO TEST(Month, Year, Value)
VALUES
(1,2013,100),
(4,2013,101),
(8,2013,102),
(2,2014,103),
(4,2014,104)
Query
DECLARE #Months Table(Month tinyint)
Insert into #Months(Month)Values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
With tblValues as (
select Rank() Over (ORDER BY y.Year, m.Month) as [Rank],
m.Month,
y.Year,
t.Value
from #Months m
CROSS JOIN ( Select Distinct Year from Test ) y
LEFT JOIN Test t on t.Month = m.Month and t.Year = y.Year
)
Select t.Month, t.Year, COALESCE(t.Value, t1.Value) as Value
from tblValues t
left join tblValues t1 on t1.Rank = (
Select Max(tmax.Rank)
From tblValues tmax
Where tmax.Rank < t.Rank AND tmax.Value is not null)
Order by t.Year, t.Month

Join unrelated tables

I want to join these two unrelated tables:
table 1
id name age
-- ---- ---
1 a 9
2 b 11
3 c 10
table 2
id school address
-- ------ -------
1 aa abc
1 aa efg
3 bb hij
Desired results:
id school address age name
-- ------ ------- --- ----
1 aa abc 9 a
1 aa efg 9 a
2 NULL NULL 11 b
3 bb hij 10 c
SELECT t1.id, t2.school, t2.address, t1.age, t1.name
FROM dbo.table1 AS t1
LEFT OUTER JOIN dbo.table2 AS t2
ON t1.id = t2.id
ORDER BY t1.id;

Resources