Sqlite select statement from 2 tables - sql

I have two tables: Products and CategoryProducts.
CategoryProducts contains:
PrdID Category
-----------------
Products contains:
PrdID Barcode Url
-----------------------
I have Product's Barcode value, for example 111111.
Need to select all Products.Url with the same Category, as this item's
Category.
Having Products.PrdID, i can get all needed PrdID's from CategoryProducts like this:
select distinct c1.PrdID
from CategoryProduct_MM c1
where c1.CategoryID in (select c2.CategoryID
from CategoryProduct_MM c2
where c2.PrdID = 175)

Based on your comment, this is what you want:
SELECT t.Url
FROM Products t
INNER JOIN CategoryProducts s
ON(s.PrdID = t.PrdID)
WHERE s.CategoryID = (select p.categoryID from CategoryProducts p
INNER JOIN Products f ON(p.prdID = f.prdID)
WHERE f.barcode = 42244)
Selects all the URLS , that their users are in the same category as PrdID ->175

SELECT
p.url
FROM
Products p
JOIN
CategoryProducts cp ON cp.PrdID = p.id
// WHERE p.id = 175
GROUP BY p.url, p.Category
And if you need add comment query

SELECT p.Url, p.PrdID
FROM Products p
JOIN CategoryProduct cp
ON p.PrdID = cp.PrdID
JOIN
Category c on c.id = cp.CategoryID AND cp.PrdID =175
// you need join table Category
Show me your Category table structure

Related

Access Subquery On mulitple conditions

This SQL query needs to be done in ACCESS.
I am trying to do a subquery on the total sales, but I want to link the sale to the province AND to product. The below query will work with one or the other: (po.product_name = allp.all_products) AND (p.province = allp.all_province); -- but it will no take both.
I will be including every month into this query, once I can figure out the subquery on with two criteria.
Select
p.province as [Province],
po.product_name as [Product],
all_price
FROM
(purchase_order po
INNER JOIN person p
on p.person_id = po.person_id)
left join
(
select
po1.product_name AS [all_products],
sum(pp1.price) AS [all_price],
p1.province AS [all_province]
from (purchase_order po1
INNER JOIN product pp1
on po1.product_name = pp1.product_name)
INNER JOIN person p1
on po1.person_id = p1.person_id
group by po1.product_name, pp1.price, p1.province
)
as allp
on (po.product_name = allp.all_products) AND (p.province = allp.all_province);
Make the first select sql into a table by giving it an alias and join table 1 to table 2. I don't have your table structure or data to test it but I think this will lead you down the right path:
select table1.*, table2.*
from
(Select
p.province as [Province],
po.product_name as [Product]
--removed this ,all_price
FROM
(purchase_order po
INNER JOIN person p
on p.person_id = po.person_id) table1
left join
(
select
po1.product_name AS [all_products],
sum(pp1.price) AS [all_price],
p1.province AS [all_province]
from (purchase_order po1
INNER JOIN product pp1
on po1.product_name = pp1.product_name)
INNER JOIN person p1
on po1.person_id = p1.person_id
group by po1.product_name, pp1.price, p1.province --check your group by, I dont think you want pp1.price here if you want to aggregate
) as table2 --changed from allp
on (table1.product = table2.all_products) AND (table1.province = table2.all_province);

Inner join base on specific condition

There are 3 tables Brand,Product and BrandProduct respectively.Table has following structure.
Brand : id,BrandName
Product : id,ProductName
BrandProduct :id,Brandid,Productid,Prize,RetailerName
I want to display the name of product,prize and retailername.This is my query.
select ProductName,Prize,RetailerName from BrandProduct BP
inner join Product P
on P.id = BP.Productid
When user select Brand,only that's brand record should come.So I changed a query.It is working properly
create proc_sample
#Brandid int = null
as
begin
select ProductName,Prize,RetailerName from BrandProduct BP
inner join Product P
on P.id = BP.Productid
inner join Brand B
on B.id = BP.Brandid
where (#Brandid is null or BP.Brandid= #Brandid)
End
When user will not select brand,join of Brand should not come.Any Idea?I know Dynamic sql come into picture.Any alternative to dynamic sql
No need to join Brand table, because BrandProduct table contains BrandId.
select ProductName,Prize,RetailerName from BrandProduct BP
inner join Product P
on P.id = BP.Productid
where (#Brandid is null or BP.Brandid = #Brandid)

How to correctly join table which may return more than one row

I have a table Items which have the following columns:
ItemId || AdminUserID || ItemName
And I try to join it with ItemAttributes:
ItemAttributeId || ItemId || AttributeValue
where one ItemId can have several ItemAttributeId values assigned to it.
I created procedure to retrieve item values from two tables:
SELECT
i.ItemID,
i.AdminUserID,
i.ItemName,
attr1.AttributeValue as IsForEmailRobotProcessingValue,
attr2.AttributeValue as RobotScheduledHoursValue -- HERE IS THE PROBLEM
FROM [dbo].[Items] i WITH (NOLOCK)
LEFT JOIN [dbo].ItemAttributes attr1 WITH(NOLOCK)
ON attr1.ItemID = i.ItemID and attr1.ItemAttributeID = 1
LEFT JOIN [dbo].ItemAttributes attr2 WITH(NOLOCK)
ON attr2.ItemID = i.ItemID and attr2.ItemAttributeID = 2
WHERE ((attr1.AttributeValue IS NOT NULL AND attr1.AttributeValue = 'true') OR
#OnlyForEmailRobotProcessing = 0)
ORDER BY ItemName
What I don't like here is that I LEFT JOIN two times the same table and created different aliases for each join according to the same ItemId. Is there any better way to LEFT JOIN only one time and created two different aliases for each ItemAttributeId? Thanks!
Try this:
SELECT
i.ItemID,
i.AdminUserID,
i.ItemName,
attr1.AttributeValue1 as IsForEmailRobotProcessingValue,
attr1.AttributeValue2 as RobotScheduledHoursValue
FROM [dbo].[Items] i WITH (NOLOCK)
LEFT JOIN
(select ItemId, (select AttributeValue
from [dbo].ItemAttributes a
where a.ItemId = b.ItemId and a.ItemAttributeID = 1) as AttributeValue1,
(select AttributeValue
from [dbo].ItemAttributes c
where c.ItemId = b.ItemId and c.ItemAttributeID = 2) as AttributeValue2
from [dbo].ItemAttributes b WITH(NOLOCK)
where b.ItemId = i.ItemID and b.ItemAttributeID in (1,2)
) attr1 on i.ItemId = attr1.ItemId
WHERE ((attr1.AttributeValue IS NOT NULL AND attr1.AttributeValue = 'true') OR
#OnlyForEmailRobotProcessing = 0)
ORDER BY ItemName

Count from another table with join

How can I Count the Lending comments for each lending (the comments is on another table called "LendingComments" with a reference Column called "LendingId" ?
SELECT LendingStatus.Status, Products.Productname, Products.Serial_number, Deposits.Amount, Lendings.DeliveryDate, Lendings.Id AS LendingId, Products.Id AS ProductId FROM Lendings
LEFT JOIN Products ON Lendings.ProductId = Products.Id
LEFT JOIN LendingStatus ON Lendings.StatusId = LendingStatus.Id
LEFT JOIN Deposits ON Lendings.DepositId = Deposits.Id
WHERE PersonId = 561 ORDER BY DeliveryDate DESC
Maby like this (if I understand the question well enough)
SELECT
LendingStatus.Status, Products.Productname, Products.Serial_number,Deposits.Amount, Lendings.DeliveryDate, Lendings.Id AS LendingId, Products.Id AS ProductId, LendingComments.NumLendingComments
FROM Lendings
LEFT JOIN Products ON Lendings.ProductId = Products.Id
LEFT JOIN LendingStatus ON Lendings.StatusId = LendingStatus.Id
LEFT JOIN Deposits ON Lendings.DepositId = Deposits.Id
OUTER APPLY
(
SELECT
COUNT(*) AS NumLendingComments
FROM
LendingComments PL
WHERE
PL.LendingID = Lendings.LendingID
) AS LendingComments WHERE Personid = 561 ORDER BY DeliveryDate desc
Maybe this helps:
SELECT CommentCount = Sum(lc.comments)
OVER (
partition BY lc.id),
lendingstatus.status,
products.productname,
products.serial_number,
deposits.amount,
lendings.deliverydate,
lendings.id AS LendingId,
products.id AS ProductId
FROM lendings
LEFT JOIN products
ON lendings.productid = products.id
LEFT JOIN lendingstatus
ON lendings.statusid = lendingstatus.id
LEFT JOIN deposits
ON lendings.depositid = deposits.id
LEFT JOIN LendingComments lc
ON lc.LendingId = lendings.Lendings.Id
WHERE personid = 561
ORDER BY deliverydate DESC
However, you have not shown the PersonLendings table, have you?
Try this one -
SELECT ls.status
, p.Productname
, p.Serial_number
, d.AMOUNT
, l.DeliveryDate
, l.Id AS LendingId
, p.Id AS ProductId
, pl.cnt
FROM dbo.Lendings l
LEFT JOIN (
SELECT pl.LendingId, cnt = COUNT(pl.LendingComments)
FROM dbo.PersonLendings pl
GROUP BY pl.LendingId
) pl ON pl.LendingId = l.LendingId
LEFT JOIN dbo.Products p ON l.ProductId = p.Id
LEFT JOIN dbo.LendingStatus ls ON l.StatusId = ls.Id
LEFT JOIN dbo.Deposits d ON l.DepositId = d.Id
WHERE PersonID = 561
ORDER BY l.DeliveryDate DESC

SQL to generate report of entity-attribute-value structured data

I have 3 tables:
Productmaster:
ProductId PName PDescription
Attributes:
AttributeID attName
---- ----
1 Brand
2 Category
3 Artist
ProductAttributeValues
paId ProductId AttributeID AttributeValues
A product can have multiple attributes.
Here's the desired output:
ProductId ProductDesc Brand Category Artist
--- --- --- --- ---
1 sadasd Brand1 Category1 Artist1
2 sadasds Brand2 Category3 Artist4
How can I get this output?
Thanks in advance.
You should left join for each attribute value you want to pull in, e.g.
select p.ProductId,p.ProductDesc,
a1.AttributeValues as Brand,
a2.AttributeValues as Category,
a3.AttributeValues as Artist,
from Product p
left join ProductAttributeValues a1 on(p.ProductId=a1.ProductId and a1.AttributeID=1)
left join ProductAttributeValues a2 on(p.ProductId=a2.ProductId and a2.AttributeID=2)
left join ProductAttributeValues a3 on(p.ProductId=a3.ProductId and a3.AttributeID=3)
To turn this back into English, "give me all products, and for each one, give me a brand, category and artist attribute if they exist"
I've assumed that a product has only one or zero values for each attribute.
Assumed that every attribute appears exactly once per product:
SELECT
pm.ProductId as ProductId,
pm.PDescription as ProductDesc,
pav_Brand.AttributeValues as Brand,
pav_Category.AttributeValues as Category,
pav_Artist.AttributeValues as Artist
FROM
ProductMaster pm
inner join ProductAttributeValues pav_Brand
on pm.productId == pav_Brand.ProductId
inner join Attributes a_Brand
on pav_Brand.AttributeId = a_Brand.AttributeId
AND a_Brand.attName = 'Brand'
inner join ProductAttributeValues pav_Category
on pm.productId == pav_Category.ProductId
inner join Attributes a_Category
on pav_Category.AttributeId = a_Category.AttributeId
AND a_Brand.attName = 'Category'
inner join ProductAttributeValues pav_Artist
on pm.productId == pav_Artist.ProductId
inner join Attributes a_Artist
on pav_Category.AttributeId = a_Artist.AttributeId
AND a_Brand.attName = 'Artist'
You can use left outer joins if the data is not always available.
SELECT ProductId, ProductDesc,
(
SELECT AttributeValues
FROM ProductAttributeValues pv
WHERE pv.AttributeID = 1
AND pv.ProductID = p.ProductID
) AS Brand,
(
SELECT AttributeValues
FROM ProductAttributeValues pv
WHERE pv.AttributeID = 2
AND pv.ProductID = p.ProductID
) AS Category,
(
SELECT AttributeValues
FROM ProductAttributeValues pv
WHERE pv.AttributeID = 3
AND pv.ProductID = p.ProductID
) AS Artist
FROM Products p
Try this query, maybe some tweak required
Select pm.ProductId, pm.PDescription, pav1.AttributeValues, pav2.AttributeValues, pav3.AttributeValues
from Productmaster pm, ProductAttributeValues pav1, ProductAttributeValues pav2, ProductAttributeValues pav3
where pm.ProductId = pav1.ProductId
and pav1.AttributeID = 1
and pm.ProductId = pav2.ProductId
and pav2.AttributeID = 2
and pm.ProductId = pav3.ProductId
and pav3.AttributeID = 3