SQL Server Query for values within same Table - sql

I have a data table (not very well structured) in which I have the following
ClientID | Parameter | Value
111..........Street..........Evergreen
111..........Zip................75244
111..........Country.........USA
222..........Street..........Evergreen
222..........Zip................75244
222..........Country.........USA
333..........Street..........Evergreen
333..........Zip................75240
333..........Country.........USA
444..........Street..........Evergreen
444..........Zip................75240
444..........Country.........USA
555..........Street..........Evergreen
555..........Zip................75240
555..........Country.........USA
666..........Street..........Some Street
666..........Zip................75244
666..........Country.........USA
For this I want to Select all those Client ID that are on Street = Evergreen BUT also with ZIP 75244, I have over 700K rows so, exporting all would be a big issue.
My idea was:
SELECT ClientID
from (select ClientID from table1 where Value = 'evergreen')
Where Zip = '75244'
But it wont give me the accurate results in this case I would like to get the values for ClientIDs 111 and 222 because the match the criteria Im looking for Street= Evergreen adn Zip=75244
Is there a way to do this?

Select ClientId from MyTable e
inner join MyTable z On e.clientId = z.ClientID
Where e.value = 'Evergreen' and e.Parameter = 'Street'
and z.parameter = 'Zip' and z.Value = '75244'
Just use an alias with a join so you can "use your table twice"

Try this:
select clientid
from table1
where (parameter='Street' and value='Evergreen')
and clientid in (select clientid from table1 where parameter='Zip' and value='75244')

Try this
Select e.ClientId from Table1 e
Where e.value in ('Evergreen','75244')
GROUP BY e.ClientId
HAVING count(distinct e.value) = 2

Related

Query table with all names in one statement

I have a table that I cannot alter and I am trying to wrap my head around an appropriate way to query this table in one statement based on one given value.
Roughly here's what the table looks like:
What I'm after is a way to query the table using only the SubBody code in order to get all names associated with it.
for example,
<query> where SubBody = '1001'
returns
| HName | HSName | BName | BSName |
+-----------------------------------+
| Toys | Sport | Ball | Baseball |
SELECT Head.Name as HName ,
SubHead.Name as HSName ,
Body.Name as BName ,
SubBody.Name as BSName
FROM yourTable as SubBody
JOIN yourTable as Body
ON SubBody.Body = Body.Body
AND Body.SubBody IS NULL
JOIN yourTable as SubHead
ON Body.SubHead = SubHead.SubHead
AND SubHead.Body IS NULL
JOIN yourTable as Head
ON SubHead.Head = Head.Head
AND Head.SubHead IS NULL
WHERE SubBody.SubBody = '1001'
Although you can express the logic as joins, for some reason correlated subqueries come to mind first:
select (select th.name from t th where th.head = t.head and th.subhead is null) as hname,
(select ts.name from t ts where ts.head = t.head and ts.subhead = t.subhead and t.body is null) as sname,
(select tb.name from t tb where tb.head = t.head and tb.subhead = t.subhead and tb.body = t.body and tb.subbody is null) as bname,
t.name as bsname
from t
where t.subbody = 1001
This answer is close to what Juan Carlos has posted. Which one you like depends a bit on your style.
WITH BaseRecord AS(
SELECT *
FROM ToyTable
WHERE SubBody = '1001'
)
SELECT
h.Name AS HName,
hs.Name AS HSName,
b.Name AS BName,
bs.Name AS BSName
FROM BaseRecord bs
INNER JOIN ToyTable b ON bs.Body = b.Body AND ISNULL(b.SubBody,'') = ''
INNER JOIN ToyTable hs ON bs.SubHead = hs.SubHead AND ISNULL(hs.Body,'') = ''
INNER JOIN ToyTable h ON bs.Head = h.Head AND ISNULL(h.SubHead,'') = ''
I'm not sure whether your "empty" cells contain nulls or empty strings. Either way, both are taken into account here.

Null value not getting picked in coalesce sql

I have created a query to fetch values from mapping staging table for location and job code
SELECT ORG_NAME,
COALESCE(JOB_MAP.FUSION_HARMONIZED_CODE,JOB_CODE) JOB_CODE,
JOB_SET_CODE,
COALESCE(LOC_MAP.FUSION_HARMONIZED_CODE,LOCATION_CODE)LOCATION_CODE
FROM XX_POS POS_STAG,
XX_MAP JOB_MAP,
XX_MAP LOC_MAP
WHERE JOB_MAP.SOURCE_CORE_HR_CODE(+)= POS_STAG.JOB_CODE
AND JOB_MAP.TABLE_CODE(+) ='JOB'
AND POS_STAG.BUSINESS_UNIT_NAME =JOB_MAP.business_unit
AND LOC_MAP.TABLE_CODE(+) ='LOC'
AND LOC_MAP.SOURCE_CORE_HR_CODE(+) = POS_STAG.LOCATION_CODE
AND POS_STAG.BUSINESS_UNIT_NAME =LOC_MAP.BUSINESS_UNIT;
But this query is not picking up value for location_code which is null in xx_pos table. Do i have to change my where condition ?
I think this is the query you want:
SELECT ORG_NAME,
COALESCE(JOB_MAP.FUSION_HARMONIZED_CODE, JOB_CODE) as JOB_CODE,
JOB_SET_CODE,
COALESCE(LOC_MAP.FUSION_HARMONIZED_CODE, LOCATION_CODE) as LOCATION_CODE
FROM XX_POS POS_STAG LEFT JOIN
XX_MAP JOB_MAP
ON JOB_MAP.SOURCE_CORE_HR_CODE = POS_STAG.JOB_CODE AND
JOB_MAP.TABLE_CODE = 'JOB' LEFT JOIN
XX_MAP LOC_MAP
ON LOC_MAP.SOURCE_CORE_HR_CODE = POS_STAG.LOCATION_CODE AND
LOC_MAP.BUSINESS_UNIT = POS_STAG.BUSINESS_UNIT_NAME AND
LOC_MAP.TABLE_CODE = 'LOC';

SQL Joining tables with 'constants'

I have a table of orders,
Invoice Location Customer Code SalesPersonEmail
------------------------------------------------------
300001 001 CUS001 ?
300002 006 CUS002 ?
And a table of email groups,
Role Email
-----------------------------------------------------
Filtered_Group Management#gmail.com;john#gmail.com
When Location = 001, SalesPersonEmail must be the Email field from Filtered_Group
SalesPersonEmail for all other locations must be "Orders#gmail.com;" + the Email for Role No_Filter_Group.
I'm currently using the following to achieve this,
SELECT i.Invoice, i.Location, i.[Customer Code],
CASE WHEN i.Location = 001
THEN f.Email
ELSE N'Orders#gmail.com;' + nf.Email as SalesPersonEmail
END
FROM Invoice i, RoleCodes f, RoleCodes nf
WHERE f.Role = N'Filtered_Group' AND nf.Role = N'No_Filter_Group'
My problem is the Role No_Filter_Group may not exist in the Role table at times, which causes the above query to return nothing.
How do I join these tables properly so if No_Filter_Group does not exist in the table, rows that have a SalesPersonEmail of Filtered_Group are still returned from the query?
Thanks
A relatively simple way is to use LEFT JOIN and put the special number 001 for your location and special role names Filtered_Group and No_Filter_Group in the join condition.
In this SQL Fiddle you can comment/uncomment one line in the schema definition to see how it works when RoleCodes has a row with No_Filter_Group and when it doesn't.
In any case, the query would return all rows from Invoice table.
SELECT
Invoice.Invoice
,Invoice.Location
,Invoice.[Customer Code]
,CASE WHEN Invoice.Location = '001'
THEN RoleCodes.Email
ELSE 'Orders#gmail.com;' + ISNULL(RoleCodes.Email, '')
END AS SalesPersonEmail
FROM
Invoice
LEFT JOIN RoleCodes ON
(Invoice.Location = '001'
AND RoleCodes.Role = 'Filtered_Group')
OR
(Invoice.Location <> '001'
AND RoleCodes.Role = 'No_Filter_Group')
Try something like this.
Note: This is just a example am not sure about the tables and column of your schema. Replace with the respective tables and columns
SELECT CASE
WHEN location = '001' THEN (SELECT TOP 1 email
FROM email_table
WHERE [role] = 'Filtered_Group')
ELSE 'Orders#gmail.com;'
END
FROM orders
If email_table table will have only one row for [role] = 'Filtered_Group' then you can remove the TOP 1 from the sub-query
Left join or an easier, albeit less efficient method would be to do a subquery in the select statement itself.
SELECT i.Invoice, i.Location, i.[Customer Code],
CASE WHEN i.Location = 001
THEN (SELECT TOP 1 f.Email FROM RoleCodes f WHERE f.Role = N'Filtered_Group')
ELSE N'Orders#gmail.com;' + ISNULL( (SELECT nf.Email as SalesPersonEmail FROM RoleCodes nf WHERE nf.Role = N'No_Filter_Group'), '')
END
FROM Invoice i
Normally you would want to join these in on each other but I'm not certain how you would do that with the schema provided.
Nested select will be run for each row, instead, you could try this :-
Select i.Invoice
,i.Location
,i.CustomerCode
,Isnull(r.Email,'Orders#gmail.com') As SalesPersonEmail
From Invoice As i With (Nolock)
Left Join
(
Select rc.Email
,'001' As Location
From RoleCodes As rc With (Nolock)
Where rc.Role = 'Filtered_Group'
) As r On i.Location = r.Location
use the following Query:
select t.Invoice,t.Location,t.[Customer Code],
case t.Location
when '001' then
t2.Email
else
'Orders#gmail.com'
end
as
Salespersonemail
from orders t
join email_groups t2 on t2.Role='Filtered_Group'

Only return value that matches the ID on table 1

I have tried all possible joins and sub-queries but I cant get the data to only return one value from table 2 that exactly matches the vendor ID. If I dont have the address included in the query, I get one hit for the vendor ID. How can I make it so that when I add the address, I only want the one vendor that I get prior to adding the address.
The vendor from table one must be VEN-CLASS IS NOT NULL.
This was my last attempt using subquery:
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENMAST.VENDOR_CONTCT,
APVENMAST.TAX_ID,
Subquery.ADDR1
FROM (TEST.dbo.APVENMAST APVENMAST
INNER JOIN
(SELECT APVENADDR.ADDR1,
APVENADDR.VENDOR_GROUP,
APVENADDR.VENDOR,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENADDR APVENADDR
INNER JOIN TEST.dbo.APVENMAST APVENMAST
ON (APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP)
AND (APVENADDR.VENDOR = APVENMAST.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)) Subquery
ON (APVENMAST.VENDOR_GROUP = Subquery.VENDOR_GROUP)
AND (APVENMAST.VENDOR = Subquery.VENDOR))
INNER JOIN TEST.dbo.APVENLOC APVENLOC
ON (APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENLOC.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)
Try this:
SELECT APVENMAST.VENDOR_GROUP
, APVENMAST.VENDOR
, APVENMAST.VENDOR_VNAME
, APVENMAST.VENDOR_CONTCT
, APVENMAST.TAX_ID
, APVENADDR.ADDR1
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN (
select VENDOR_GROUP, VENDOR, ADDR1
, row_number() over (partition by VENDOR_GROUP, VENDOR order by ADDR1) r
from TEST.dbo.APVENADDR
) APVENADDR
ON APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP
AND APVENADDR.VENDOR = APVENMAST.VENDOR
AND APVENADDR.r = 1
--do you need this table; you're not using it...
--INNER JOIN TEST.dbo.APVENLOC APVENLOC
--ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
--AND APVENMAST.VENDOR = APVENLOC.VENDOR
WHERE APVENMAST.VEN_CLASS IS NOT NULL
--if the above inner join was to filter results, you can do this instead:
and exists (
select top 1 1
from TEST.dbo.APVENLOC APVENLOC
ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
AND APVENMAST.VENDOR = APVENLOC.VENDOR
)
I found another column in the APVENLOC table that I can filter on to get the unique vendor. Turns out if the vendor address is for the main office, the vendor location is set blank.
Easier than I thought it would be!
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENADDR.ADDR1,
APVENMAST.VENDOR_SNAME,
APVENADDR.LOCATION_CODE,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN TEST.dbo.APVENADDR APVENADDR
ON (APVENMAST.VENDOR_GROUP = APVENADDR.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENADDR.VENDOR)
WHERE (APVENADDR.LOCATION_CODE = ' ')
Shaji

how to join two tables where second table has condtion

I have two tables like
shopping_cart_table and customer_table
shopping_cart_table has fields shoppingcart_id | home_No|
customer_table has fields shoppingcart_id | status| customer_type|
I want to get the home_No from shopping_cart_table WHERE (customer_table.status is null OR customer_table.status='Y') AND customer_table.customer_type='X'
both table can join from shoppingcart_id
Actually this is just basic.
You can use join & put where conditions.
Select a.home_No
from shopping_cart_table as a
inner join customer_table as b
on a.shoppingcart_id = b.shoppingcart_id
where nvl(b.status,'Y') = 'Y'
and customer_type='X'
select home_No
from shopping_cart_table, customer_table
WHERE shopping_cart_table.shoppingcart_id = customer_table.shoppingcart_id
AND(customer_table.status is not null OR customer_table.status='Y') AND
customer_table.customer_type='X'
But this condition looks a bit strange:
(customer_table.status is not null OR customer_table.status='Y')
Maybe you'd want to change it for
nvl(customer_table.status,'Y')='Y'
aqssuming that 'not' was put there by a mistake
You can try this query:
SELECT sct.home_no
FROM shopping_cart_table AS sct
, customer_table AS ct
WHERE sct.shoppingcart_id = ct.shoppingcart_id
AND (
ct.status IS NOT NULL
OR ct.status = 'Y')
AND ct.customer_type = 'X'