I am trying to retrieve the CategoryID and CategoryName by seeing the CategoryBusinessMapping and Review Rating table. I am trying to retrieve the data of following Category table:
Category ParentCategoryID CategoryName
1 null Education
2 1 School
3 null Health
4 3 Doctors
5 1 Colleges
I have the Business table which has BusinessID and BusinessName and BusinessDescription like this:
BusinessID BusinessName BusinessDescription
YP00001 XYZ ABCD
YP00002 ABC XYZA
I have the CategoryBusinessMapping table like this:
MappingID CategoryID BusinessID
1 1 YP00001
2 2 YP00001
3 5 YP00001
4 3 YP00002
5 4 YP00002
I have this mapping table to map the different Category with the Business. I also have the Rating table like this:
RatingID BusinessID
1 YP00001
2 YP00001
3 YP00001
4 YP00002
5 YP00002
Here in this table I am assuming that a record having same BusinessID is fall under most popular Business. Meaning, here in above the Business ABCD having ID = YP00001 has four records in Rating table. Therefore it falls under most popular Business. Similarly YP00002 falls next to YP00001. By seeing the most popular Business in descending order I want to retrieve CategoryName and CategoryID. I have tried this to retrieve from the Rating table only:
select Distinct ReviewRating.BusinessID
,Count(*)as Rating
from YP.utblYPReviewRatingDtls as ReviewRating
group by ReviewRating.BusinessID
order by Rating desc
I have tried this:
SELECT distinct c.CategoryName, b.BusinessID
FROM Category c
INNER JOIN categoryBusinessMapping cbm
ON (c.CategoryID=cbm.CategoryID)
INNER JOIN Business b
ON (cbm.BusinessID=b.BusinessID)
LEFT JOIN Rating r
ON (cbm.BusinessID=r.BusinessID)
where c.ParentCategoryID is null
but I get the result which is redundant. I also remove the BusinessID from the query and I get the result but the result is incorrect. How can I remove redundancy and also get the proper output?
Use join and take the count of BusinessID from rating table and order your results
SELECT c.*, COUNT(r.BusinessID) AS bcount FROM Category c
INNER JOIN CategoryBusinessMapping cbm ON (c.Category=cbm.CategoryID)
INNER JOIN Business b ON (cbm.BusinessID=b.BusinessID)
LEFT JOIN Rating r ON (cbm.BusinessID=r.BusinessID)
GROUP BY r.BusinessID
ORDER BY bcount DESC
Related
I want to join columns from multiple tables to one column, in my case column 'battery_value' and 'technical_value' into column 'value'. I want to fetch data for only given category_ids, but because of UNION, I get data from other tables as well.
I have 4 tables:
Table: car
car_id model_name
1 e6
Table: battery
battery_category_id car_id battery_value
1 1 125 kW
Table: technical_data
technical_category_id car_id technical_value
1 1 5
3 1 2008
Table: categories
category_id category_name category_type
1 engine power battery
1 seats technical
3 release year technical
From searching, people are suggesting that I use union to join these columns. My query now looks like this:
SELECT CARS.car_id
category_id,
CATEGORIES.category_name,
value,
FROM CARS
left join (SELECT BATTERY.battery_category_id AS category_id,
BATTERY.car_id AS car_id,
BATTERY.value AS value
FROM BATTERY
WHERE `BATTERY`.`battery_category_id` IN (1)
UNION
SELECT TECHNICAL_DATA.technical_category_id AS category_id,
TECHNICAL_DATA.car_id AS car_id,
TECHNICAL_DATA.value AS value
FROM TECHNICAL_DATA
WHERE `TECHNICAL_DATA`.`technical_category_id` IN (3))
tt
ON CARS.car_id = tt.car_id
left join CATEGORIES
ON category_id = CATEGORIES.id
So the result I want is this, because I only want to get the data where category_id 1 is in battery table:
car_id category_id category_name technical_value
1 1 engine power 125 kW
1 3 release year 2008
but with the query above I get this, category_id 1 from technical table is included which is not something I want:
car_id category_id category_name value
1 1 engine power 125 kW
1 1 seats 125 kW
1 3 release year 2008
How can get exclude the 'seats' row?
For the results you want, I don't see why the cars table is needed. Then, you seem to need an additional key for the join to categories based on which table it is referring to.
So, I suggest:
SELECT tt.*, c.category_name
FROM ((SELECT b.battery_category_id AS category_id,
b.car_id AS car_id, b.value AS value,
'battery' as which
FROM BATTERY b
WHERE b.battery_category_id IN (1)
) UNION ALL
(SELECT td.technical_category_id AS category_id,
td.car_id AS car_id, td.value AS value,
'technical' as which
FROM TECHNICAL_DATA td
WHERE td.technical_category_id IN (3)
)
) tt LEFT JOIN
CATEGORIES c
ON c.id = tt.category_id AND
c.category_type = tt.which;
That said, you seem to have a problem with your data model, if the join to categories requires "hidden" data such as the type. However, that is outside the scope of the question.
In one fruit there can be multiple tickets that can be raised. I need to display the number of tickets raised per fruit. Their key field is the fruit_id.
If I have the following tables:
fruit
id name
1 apple
2 orange
tickets
id fruit_id
1 1
2 1
3 2
4 2
5 2
Then I would use the following SQL syntax to output a table like the one you need:
SELECT fruit.id, fruit.name, COUNT(tickets.id)
FROM tickets
LEFT JOIN fruit ON fruit.id = tickets.fruit_id
GROUP BY fruit.id;
Output:
id name COUNT(tickets.id)
1 apple 2
2 orange 3
SELECT Fruit.Fruit ID,Fruit.Fruit Name, count(Ticket.Ticket Id) as match_rows FROM Fruit LEFT Join Ticket on (Fruit.Fruit ID = Ticket.Fruit ID) group by Fruit.Fruit Id ORDER BY Fruit.Fruit ID DESC
I need a quick way to find the Number of items in a table. The items are linked to an other table. Table 1 is products and table 2 is orders.
Orders contains a paid status (1 or 0).
Orders table example:
id paid
1 0
2 1
Products table example:
id orderid type
1 1 5
2 1 5
3 1 3
4 2 5
5 2 5
6 2 3
Products contains a id (orderid) that refers to the order and a type. So i need the number of products where type = 5 and paid = 1 in the orders table.
What is the best and fastest way to archieve this?
So I need all the paid products with type 5. The result should be '2'.
you can use join like this,
SELECT COUNT(*) AS num_rows
FROM products
LEFT JOIN orders ON orders.id = products.orderid
WHERE type = 5 AND paid = 1
One way is to use a join statement. Making some assumptions about your schema, the following should work:
SELECT COUNT(p.`id`) FROM `products_table` p
LEFT JOIN `orders_table` o ON p.`orderid` = o.`id`
WHERE o.`paid` = 1
AND p.`type` = 5
I am making queries to extract data from database which holds customer order. There's one table which holds customer id's and the customer's name. Another table which has the order id, customer id of who placed the order, a quantity of the item bought, and an item id. The last table holds the item id's and item names. I am trying to sort these to show an individual's most popular purchase, but am having issues properly grouping and ordering to produce the correct result, below is an example of what is intended.
customers
1 | John
---+-----
2 | Jane
orders
1 | 2 | 4 | 1
---+---+---+---
2 | 2 | 5 | 2
---+---+---+---
3 | 2 | 2 | 1
---+---+---+---
4 | 1 | 1 | 2
items
1 | Chair
---+-------
2 | Sofa
After properly sorting and grouping, the output table should like:
John | Sofa
------+------
Jane | Chair
Currently I can connect the item names to the purchaser and return a random item bought, but not the most popular by quantity. I have tried entering multiple fields into group by and managed to properly group the items by name and sort by quantity, but in doing so the customer id's became ungrouped. Been trying to solve this for days so any help would be appreciated. Please note that this is a very simplified version of the actual problem where many more tables are involved, including multiple items table which are being joined together to one.
You should use group by on joined tables
select
b.name
, c.name
, sum(quantity) as tot
from orders as a
inner join Customers as b on a.customer_id = b.id
inner join Items as c on a.item_id = c.id
group by b.name, c.name
order by tot
Selecting the sum of the quantities per customer-item group is easy, but selecting the top seller is a bit harder.
The first step is the query to get all the groups with the sums of the quantities for each customer-item:
SELECT
customer_name,item_name,SUM(quantity)
FROM
orders o
JOIN customers c ON o.customer_id=c.id
JOIN items i ON o.item_id=i.id
GROUP BY customer_name,item_name;
Then to only select the groups with the maximum quantity sums we use some trickery:
SELECT
customer_name,item_name,SUM(quantity),
(SELECT SUM(quantity) AS qmax
FROM
orders o2
JOIN customers c2 ON o2.customer_id=c2.id
JOIN items i2 ON o2.item_id=i2.id
WHERE c2.id=c.id
GROUP BY c2.customer_name,i2.item_name
ORDER BY qmax DESC LIMIT 1) AS qmax
FROM
orders o
JOIN customers c ON o.customer_id=c.id
JOIN items i ON o.item_id=i.id
GROUP BY customer_name,item_name
HAVING SUM(quantity)=qmax;
Edit:
Here's a link to a fiddle: SQLFiddle
I'm trying to find the leagues (lid) where two users are apart of.
Here are my tables:
Table leagues:
*id* lname
--------------
1 Hard C
3 Fun
5 Crazy
Table match:
*userid* *lid*
-----------------
1 1
4 5
1 3
2 1
4 1
4 3
*Are primary keys
match.lid is foreign key to leagues.id (a user cannot not be part of the same league twice)
Here's what I have so far (a start):
SELECT t1.lid, t2.lname
FROM match t1
JOIN leagues t2 on t1.lid = t2.id
So far I managed to join the two tables and get the names. My ultimate goal is to show the lid's where two users are part of the same league, say userid 1 and 4.
userid 1 is a member of lid 1 and 3
userid 4 is a member of lid 5, 1, and 3
Both users meet in league(lid) 1 and 3
So I need a query that shows only the league where both users meet. Like this:
lid lname
--------------
1 Hard C
3 Fun
Since userid 1 and 4 meet in league 1 and 3, the results should show that. I can run two queries for each user and check which leagues both users meet via php, but I think it's more efficient to run one query.
SELECT m1.lid, l.lname FROM
`match` m1, `match` m2, leagues l
WHERE m1.lid = m2.lid AND m1.lid = l.id
AND m1.userid = 1
AND m2.userid = 4
There are a few ways. The most straightforward is:
SELECT id AS lid,
lname
FROM leagues
WHERE id IN
( SELECT lid
FROM match
WHERE userid = 1
)
AND id IN
( SELECT lid
FROM match
WHERE userid = 4
)
;
Another way, which is a bit less direct, but may perform better — you can try it and see — is to use JOIN:
SELECT id AS lid,
lname
FROM leagues
JOIN match AS match1
ON match1.lid = leagues.id
AND match1.userid = 1
JOIN match AS match2
ON match2.lid = leagues.id
AND match2.userid = 4
;