SQL Server select by grouping - sql

Table 1
csstatus
csid status
122 defaulter
123 regular
124 registery
125 defaulter
table 2
csplotdetials
csid plotsize
122 50
123 25
124 30
125 25
qunery result
Status totalplotsize
defaulter 75
regular 25
....
how i can do that both tables are not in relationship they are in realtionship with another table

SELECT status, sum(plotsize) as totalplotsize
FROM csstatus cs
INNER JOIN csplotdetials cp ON cs.csid = cp.csid
GROUP BY status

I'm assuming that tables are linked via csID coluymn from both tables.
SELECT a.csID, a.status, SUM(b.plotsize) totalPlotSize
FROM ccstatus a
INNER JOIN csplotdetails b
On a.csID = b.csID
GROUP BY a.csID, a.status
SQLFiddle Demo
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins

I must be missing something here, because it looks like I can infer a relationship between the two tables (on the csid column) to produce the results you are after:
SELECT csstatus.status AS Status, SUM(csplotdetials.plotsize) AS totalplotsize
FROM csplotdetials
INNER JOIN csstatus ON csplotdetials.csid = csstatus.csid
GROUP BY csstatus.status
SQL Fiddle example

Related

Select records that do not have a product associated on a second table

I have two tables:
Table PL:
plid
plname
1
Alice
2
John
3
Danielle
And table PLproducts
plid
productIdentifier
1
membership
1
life
1
dental
2
membership
3
membership
3
life
3
auto
I need to find those plid where productIdentifier does not contain "dental"
Expected results:
plid
plname
2
John
3
Danielle
If I Outer Join for PLproducts <> 'dental', I get all the records that do not contain 'dental' but that is not what Im looking for.
I've never found this scenario before. I understand it may be a simple question.
Thank you all.
You're looking for where something does not exist
select *
from pl
where not exists (
select * from plProducts p
where p.plid = pl.plid and p.productidentifier = 'dental'
);
There are multiple ways to approach this problem. You might be interested in looking at cross apply. It could be a useful approach in more complicated scenarios.
select pl.*
from pl cross apply (
select count(*) as hasdental from plproducts pp
where pp.plid = pl.plid and p2.productidentifier = 'dental'
) as oa
where hasdental = 0;
One of the methods is using string_agg and then use having to remove the phrases that includes "dental".
select * from PL p1
where p1.plid in
(select p2.plid from PLproducts p2
group by p2.plid
having STRING_AGG(productIdentifier,';') NOT LIKE N'%dental%')

SQL Join limiting left table by right

I need to do a SQL Query where I pull users that are in Table 1 and either not in table 2 at all, or not in a specific subset of table 2.
Here is what I have:
Table ClientUsers
ID UserName
1 User1
2 User2
3 User3
4 User4
5 User5
Table UserRoles
ClientUsersID ClientRolesID
1 101
2 166
5 103
I need to select all users that are either in UsersRoles with any ClientRoleID that is not 166 OR not in User Roles at all.
So in this case, I would select users 1, and 3-5. 1 and 5 because they are in table UserRoles with a role other than 166, and 3 and 4 because they are in table ClientUsers but NOT table UserRoles at all.
I haven't been able to use a null in the WHERE statement because then it's looking for a null value in a column, as opposed to a row that doesn't exist.
I think that I have to use a full outer join, then narrow the results, but I haven't found a query that works yet.
SELECT * FROM dbo.ClientUsers
FULL OUTER JOIN dbo.UserRoles on ClientUsers.ID = UserRoles.ClientUsersID
WHERE UserRoles.ClientRolesID != 166 OR [value not in right table]
I don't know how to replace that bracket with something that will work (or redo the query entirely).
Use not exists:
SELECT cu.*
FROM dbo.ClientUsers cu
WHERE NOT EXISTS (SELECT 1
FROM dbo.UserRoles ur
WHERE cu.ID = ur.ClientUsersID AND ur.ClientRolesID = 166
);
This is almost a direct translation of your problem statement.
How about this?
SELECT *
FROM dbo.ClientUsers
FULL OUTER JOIN dbo.UserRoles on ClientUsers.ID = UserRoles.ClientUsersID
WHERE UserRoles.ClientRolesID != 166 or UserRoles.ClientRolesID is NULL;

SQL Lookup data in joined table based on LIKE value stored in joined table column

I am trying to build a query that will look up a product_subcategory based on a reference data in a user entered table and joining two tables together. My database is SQL Server 2012 Express.
First the products table has three columns: Product_id (unique identifier), event_id (INT data type), and product_category. (product_category needs to be alphanumeric currently varchar(32) data type)
Example Products table data:
Product_id event_id product_category
1 20 100
2 20 105
3 20 200
4 21 100
5 21 200
6 21 203
7 22 105
8 22 207
Second the events table has two columns: event_id (unique identifier, INT Data type) and zone (float data type, not sure why this was setup as float, probably should have been INT but its a pre-existing table and I don't want to change it)
event_id zone
20 1
21 2
22 3
Third the subcategory table has four columns: subcategory_id (unique identifier, INT data type), zone (joins to zone column in products table, INT Data type), category_lookup (varchar(max) data type), and product_subcategory (varchar(50) data type). This is a table that I am creating for this project so I can change the structure or datatypes to be whatever is needed for the project, I don't have that flexibility on the other tables.
Example Subcategory table data:
subcategory_id zone category_lookup product_subcategory
1 1 '1%' 25
2 1 '2%' 23
3 2 '1%' 26
4 2 '2%' 30
I want to build a query that will search the product table and match a zone, product_category, and product_subcategory together based on the value in the subcategory.category_lookup column.
The data that I want returned from the query is:
product_ID zone product_category product_subcategory
1 1 100 25
2 1 105 25
3 1 200 23
4 2 100 26
5 2 200 30
6 2 203 30
7 3 105 NULL or 'N/A'
8 3 107 NULL or 'N/A'
The logic behind looking up the matching subcategory will be similar to below: (this is essentially what is stored in the subcategory table) (the text in the “quotes” is what I mean by reference data, and will be user entered)
IE... if zone = 1 and product_category “begins with 1” then product_subcategory = 25
IE... if zone = 1 and product_category “begins with 2” then product_subcategory = 23
IE... if zone = 2 and product_category “begins with 1” then product_subcategory = 26
IE... if zone = 2 and product_category “begins with 2” then product_subcategory = 30
I do understand that one of the issues with my logic is that if multiple subcategories match to one product then it will throw an error, but I think I can code around that once I get this part of it working
I am fine going a different direction with this project but this is the first way I decided to tackle it. The most important component is that the product_subcategory’s are going to be located in a separate user entered table, and there needs to be user entered logic as discussed above to determine the product_subcategory based on zone and product_category.
I am not a SQL guru at all so I don’t even know where to start to handle this problem. Any advice is appreciated.
Based on answers I have received so far I have come up with this:
SELECT p.product_id, p.event_id, e.zone, p.product_category, sc.product_subcategory
FROM Products p
LEFT JOIN events e on p.event_id = e.event_id
LEFT JOIN SubCategory sc ON e.zone = sc.zone AND CAST(p.product_category as varchar(max)) like sc.category_lookup
But unfortunately its only returning NULL for all of the product_subcategory results.
Any additional help is appreciated.
Thanks,
This should do the trick, you will just need to modify the CAST(p.zone as nchar(10)) to insert the correct data type for your category_lookup column, in place of nchar(10), as I assume the zone in Products is an int where as the lookup column is some string based column:
SELECT p.product_id, p.zone, p.product_category, sc.product_subcategory
FROM Products p
LEFT JOIN SubCategory sc ON p.zone = sc.zone
AND CAST(p.zone as nchar(10)) like sc.category_lookup
Based on your updates, the following should work:
SELECT p.product_id, p.event_id, e.zone, p.product_category,
sc.product_subcategory
FROM Products p
INNER JOIN events e on p.event_id = e.event_id
LEFT OUTER JOIN SubCategory sc ON e.zone = sc.zone
AND CAST(e.zone as nchar(250)) LIKE CAST(sc.category_lookup as nchar(250))
Update based on comments:
SELECT p.product_id, p.event_id, e.zone, p.product_category,
sc.product_subcategory
FROM Products p
INNER JOIN events e on p.event_id = e.event_id
LEFT OUTER JOIN SubCategory sc ON e.zone = sc.zone
AND CAST(p.product_category as nchar(250)) LIKE sc.category_lookup
Working sample SQLFiddle
Not tested but is this what you're looking for ?
select a.product_ID, a.zone, a.product_category, b.product_subcategory
from Products a
inner join Subcategory on ((a.zone = b.zone) and (a.product_category like b.category_lookup))
Try this..
select p.product_id, p.zone, p.product_category, isnull(s.product_subcategory,'NA') as product_subcategory
from Products p
left outer join Subcategory s on (s.zone = p.zone and p.product_category like s.category_lookup);

Get multiple records for the same row of master table

Hi friends I struggling with following scenario in SQL table
I have Got Two tables and need a table from querying them.
table 1 is USER table (Master).
USERID USERNAME EMAILADD
113 name1 q#q.com
114 name2 b#bcom
Following is the 2nd Lookup table
userid districtid schoolid schoolNAme radius
113 12332 35831 Fort 1.0
113 2332 35832 Spring 1.0
114 2334 35831 Spring 1.0
and following is my requirement
userid username emailadd schoolid
113 name1 q#q.com 35831
113 name1 q#q.com 35832
114 name2 b#b.com 35831
I tried following query
SELECT userID , userNAME, emailadd, phone,
(SELECT schoolid from Lookup
where UserID IN(select distinct userid from users)) schoolid
FROM Users
but its not working at all.I am new to SQL server can any one please suggest a better way to achieve the result.
Use a join to connect tables
SELECT u.userID, u.userNAME, u.emailadd, u.phone, l.schoolid
FROM Users u
inner join Lookup l on u.userid = l.userid
Use a simple JOIN,
SELECT
Users.userid,username,emailadd,schoolid
FROM
Users
INNER JOIN Lookup ON Users.userid = Lookup .userid
Also you may even want to use "WITH(NOLOCK)" if your only going to select, and if there will be a lot more records you need to iterate through

In my sql script LEFT JOIN is giving output like CROSS JOIN?

I have two table like following
DailyData
Date Id CompanyName CompanyPrice CompanyId
21-12-2011 123 ABC corp 120 535
25-12-2011 352 Z Edge 101 444
25-12-2011 352 Z Edge 100 444
primary key is `date` and `Id`
ReportData
RId Date CompanyName TodayPrice CompanyId
1 25-12-2011 Z Edge 230 444
primary key is only `RId`
Now I have used following LEFT JOIN on both above table like :
Select a.date,a.companyname,a.CompanyPrice,b.TodayPrice
from DailyData a LEFT JOIN ReportData b ON
a.companyid= b.companyid where a.Date = '25-12-2011'
But instead of two records it is giving more than two records (same records multiple times)
Why is it so ?
Please help me to correct my sql query.
expected output for above data should be:
date companyname companyprice todaysprice
25-12-2011 Z Edge 101 230
25-12-2011 Z Edge 100 230
You current query is missing a JOIN on the actual columns, as a result you are getting a CROSS JOIN result of all the rows that meet the date condition. You will want to use:
Select a.date,a.companyname,a.CompanyPrice,b.TodayPrice
from DailyData a
LEFT JOIN ReportData b
ON a.CompanyId= b.CompanyId
WHERE a.Date = '25-12-2011';
See SQL Fiddle with Demo
Your Join condition: [ ON a.Date = '25-12-2011' ] does not establish any condition on table b, therefore, every row in table b is joined to each row in table a with that specified date.
From looking at the two tables it is not obvious whether the they should be joined on date or on CompanyID.
I believe you need something like
Select a.date,a.companyname,a.CompanyPrice,b.TodayPrice
from DailyData a
LEFT JOIN ReportData b ON
(b.CompanyId = a.CompanyId )
WHERE a.Date = '25-12-2011'
sql fiddle
no LEFT and no WHERE clause
Select a.date,
a.companyname,a.CompanyPrice,b.TodayPrice
from DailyData a
JOIN ReportData b
ON a.CompanyId= b.CompanyId