I have a table which is formatted as:
id | food | userID | beerID
I am trying to select all the foods for a given beerID and a count of repeats. SO if there are 3 entries for pizza I get results like:
food | beerID | count
pizza | 34 | 2
hot wings | 34 | 1
pasta | 34 | 5
Does this work? I am a bit confused on using the count with the group by.
select food, beerID , count() where beerID = 34 group by food
Give the count a parameter.
select food, beerID, count(food) from tablename as num where beerID = 34 group by food;
Footnote: "does this work" is a bad question. You'll 100% chance be rebutted with "did you not try it..?"
As noted in the comments you aren't selecting from a specific table, so it will error out
SELECT food, beerID, count(1) as beerCount
FROM tablename
WHERE beerID=34
GROUP BY food;
Related
I have a search field for an online shop that uses MySQL query for 2 different tables. The first table is vinyls which has 13 columns, and the second table is products which has 10 columns. The result I want is that if you enter a keyword, it will search the album_name and artist_name columns of table vinyls, and the name column in table products to find any matches.
My php code first counts the number of times a hit is made, and if it does, uses a query again to display the hits like online stores do. However, when I tested it, it only shows results from the vinyls table and not the products table. I've tried using UNION but because both tables have a different number of columns, it results in an error. I've used NULL to fill up the missing columns needed for union but it doesn't work too. Joins doesn't help either as the two tables do not have any similar column. What complicated it is the use of count(*) for the first query.
My SQL query using UNION and COUNT:
(SELECT COUNT(*) AS numrows
FROM vinyls
WHERE ( album_name LIKE :keyword
OR artist_name LIKE :keyword)
)
union
(SELECT COUNT(*) AS numrows
FROM products
WHERE name LIKE :keyword)
My php code for search field:
$stmt = $conn->prepare("(SELECT COUNT(*) AS numrows
FROM vinyls
WHERE ( album_name LIKE :keyword
OR artist_name LIKE :keyword)
)
union
(SELECT COUNT(*) AS numrows
FROM products
WHERE name LIKE :keyword)");
$stmt->execute(['keyword' => '%'.$_POST['keyword'].'%']);
$row = $stmt->fetch();
if($row['numrows'] < 1){
echo '<h1 class="page-header">No results found for <i>'.$_POST['keyword'].'</i></h1>';
}else{
echo '<h1 class="page-header">Search results for <i>'.$_POST['keyword'].'</i></h1>';
try{
$inc = 3;
$stmt = $conn->prepare("(SELECT *
FROM vinyls
WHERE ( album_name LIKE :keyword
OR artist_name LIKE :keyword)
)
union
(SELECT *
FROM products
WHERE name LIKE :keyword)");
$stmt->execute(['keyword' => '%'.$_POST['keyword'].'%']);
foreach ($stmt as $row) {...
I'm already stumped on how to search the 2 tables from only one search field and display the results from both tables and not only just one table. And it's a similar problem too when adding items to cart as they can be either from the two tables and I have to "join" the two tables again.
Where did I go wrong?
Edit:
Sample data
Vinyls table
+----+------------------+---------------------------+-----------+
| id | album_name | artist_name | genre |
+----+------------------+---------------------------+-----------+
| 11 | Ravel Bolero | Boston Symphony Orchestra | Classical |
| 12 | TV Calendar Show | Arthur Godfrey | Orchestra |
| 13 | Flip Phillips | The Phillips Quartet | Jazz |
| 14 | The Modern Idiom | Various artists | Jazz |
+----+------------------+---------------------------+-----------+
Products table
+----+-------------+------------------------------------------------------+
| id | category_id | name |
+----+-------------+------------------------------------------------------+
| 31 | 15 | Tonka/Diecast trucks and cars |
| 32 | 21 | Plate Number Georgia PQQ 1151 |
| 33 | 6 | Walt Disney Read Along Casette Tapes |
| 34 | 7 | Herbert Von Karajan |
| 35 | 8 | BANK IT! Board Game |
| 36 | 9 | Iraqi Most Wanted Playing Cards |
| 37 | 10 | STAR TREK ( 1991,'92,'93 ) Stamp Oasis Rubber Stamps |
| 38 | 11 | Batman and Friends Action Figure Toys (4" - 5") |
| 39 | 12 | Delta Dawn Porcelain Doll |
+----+-------------+------------------------------------------------------+
Expected result is similar to amazon's search bar, where you type a keyword and results show after you've entered. What I want in my site is that if I type orchestra in the search field, it will display Boston Symphony Orchestra's row. Or if I type cars, it will display the tonka row.
What I get is that it only shows the vinyls table and never the products table even if I type cars and there should have been a hit in the products table. Or I get an error because union is applicable only to tables with similar number of columns.
You have 2 problems in your code.
First, your count query should work and throw no error, but you only look at the first result row (the one of your vinyls). But your query returns two rows. (It will return one row with the numrows field for the first unioned query (vinyls) and one row with the numrows field for the second query (products) in your union.
You could wrap it into a SUM to only get one result row back:
$stmt = $conn->prepare("SELECT SUM(numrows) AS numrows FROM
(SELECT COUNT(*) AS numrows
FROM vinyls
WHERE ( album_name LIKE :keyword
OR artist_name LIKE :keyword)
)
union
(SELECT COUNT(*) AS numrows
FROM products
WHERE name LIKE :keyword)) AS sumQuery");
The second problem is the query, which loads your result and throws the exception because of the nonmatching column count. You have to define which columns of each of the two unioned queries should be returned, and they have to match on both. So f.e. do this:
$stmt = $conn->prepare("(SELECT id, album_name AS name, artist_name
FROM vinyls
WHERE ( album_name LIKE :keyword
OR artist_name LIKE :keyword)
)
union
(SELECT id, name, NULL AS artist_name
FROM products
WHERE name LIKE :keyword)");
Not sure if the title explains what I am trying to do correctly however I was unable to word it.
I am trying to create an output for a some graphs. The output I am aiming for is just the total value of some rows in a mySQL table grouped by a category ID. My tables are as follows:
Transactions:
TransactiondID | TransactionName |TransactionCategory| Value
*************************************************************
1 | GenericText1 | 1 | 30
2 | GenericText2 | 1 | 38
3 | GenericText2 | 2 | 38
And my Reference Data for TransactionCategory
TranCatID | TransCatName
*************************
1 | Tranportation
2 | Petrol
So what I want to do is do is a SUM of the value field by each category. So I would get an output of.
Category | Value
****************************
Transportation | 68
Petrol | 30
I got this but it does not work. I think it is completely incorrect but wanted to show my attempt.
SELECT SUM( `TransactionValue`) AS Value,
transaction_category.transaction_category
FROM Transactions
JOIN transaction_category on Transactions.TransactionID = transaction_category_id
Grouping by either "TransactionCategory" or "TranCatID" will give you the desired result shown as follows:
SELECT TransactionCategory.TransCatName, SUM( `Value`) AS Value FROM Transactions JOIN TransactionCategory on Transactions.TransactionCategory = TransactionCategory.TranCatID GROUP BY TransactionCategory.TransactionCategory;
or
SELECT TransactionCategory.TransCatName, SUM( `Value`) AS Value FROM Transactions JOIN TransactionCategory on Transactions.TransactionCategory = TransactionCategory.TranCatID GROUP BY TransactionCategory.TranCatID;
This should do the trick
SELECT TransactionCategory.TransCatName,
SUM(Transactions.Value) as Value
FROM Transactions
LEFT JOIN TransactionCategory ON TransactionCategory.TranCatID = Transaction.TransactionCategory
You can use this :
SELECT tc.TransCatName Category, SUM(t.Value) as Value
FROM TransactionCategory tc
LEFT JOIN Transactions t ON tc.TranCatID = t.TransactionCategory
group by tc.TransCatName
SQL HERE
OUTPUT
Category | Value
-----------------------
Petrol | 38
Transportation | 68
Please notice the SUM for PETROL, it should 38 as above, which is wrongly written 30 in your question description!
I have run into an issue selecting data from my MySQL database.
For example, I have a table with the following columns & tables:
Table name: farming
id | animal | amount | food
----------------------------
1 | Cow | 10 | Grass
12 | Sheep | 19 | Grass
23 | Lion | 1 | Everything
29 | Lamb | 3 | Grass
102| Pig | 8 | Everything
...
I want to get the amount from all the rows that match the food type of a selected id.
E.g. If I choose id: 102 then it would get the amount from ALL rows where the food = 'Everything'
SELECT amount FROM farming WHERE food = '".$_GET['food']."' **IS THE SAME TYPE AS IT IS IN** id = '1'"; // This should select 10, 19 and 3 from amount (as id = 1's foodtype is Grass, so it should select amount from all rows where foodtype = grass.
** is where I'm facing issues, I've tried various statements and can't seem to get it to work.
You could use group by clause which will sum up all value from amount column whre food = 'Grass'
SELECT SUM(amount) ammount FROM farming
WHERE food = (select food FROM farming where id = 102)
GROUP BY food
This should do the trick
select amount
from farming
where food = (
select food
from farming
where id = 1
)
I have a following db format set up:
id fid name time flag
1 224 Mike 112 3
2 555 John 98 5
3 224 Mike 101 0
4 121 Ann 80 1
5 224 Mike 55 7
6 121 Ann 150 4
I used following query to sort and display them grouped by fid (or name) and to sort them by lowest time:
SELECT id, fid, name, MIN(time), flag FROM dblist GROUP BY name ORDER BY MIN(time)
This works fine as I get the output in order I want. Something like:
name time
Mike 55
Ann 80
John 98
However, if I try to display fid, flag, or any other fields that are associated with that particular time record I get some other values (presumably first that query comes across).
What I would like to get is following format:
id fid name time flag
5 224 Mike 55 7
4 121 Ann 80 1
2 555 John 98 5
I am wondering if there is a way to get this done with just one database and some other query syntax?
Thanks.
Use a self join on two conditions 1 with name and with the minimum of time score for each name,group by results are indeterminate their order is not guaranteed with the latest or the first record in group
select t.* from t
join (SELECT name, MIN(`time`) `time`
FROM t GROUP BY name) t1
on(t.name = t1.name and t.`time`=t1.`time`)
order by t.`time`
Demo
use this request
SELECT
id,
fid,
name,
MIN(time),
flag
FROM
dblist
GROUP BY
id,
fid,
name
ORDER BY
MIN(time)
Query:
SQLFIDDLEExample
SELECT t.id,
t.fid,
t.name,
t.time,
t.flag
FROM t t
LEFT JOIN t t1
ON t.fid = t1.fid
AND t.time > t1.time
WHERE t1.time is null
Result:
| ID | FID | NAME | TIME | FLAG |
|----|-----|------|------|------|
| 2 | 555 | John | 98 | 5 |
| 4 | 121 | Ann | 80 | 1 |
| 5 | 224 | Mike | 55 | 7 |
I need to do a SUM of all points (hiscore) for each player.
For now I'm able to sum either player1 or player 2. So for example in category 7, player 1 is Tom, and in category 5 player 2 is also Tom. Result should be Tom = 2+10 = 12 points.
SELECT SUM(subpoints) AS hiscore, player1_id, player2_id, FROM (
SELECT COUNT(current_record)*2 AS subpoints, player1_id, player2_id FROM db WHERE category_id IN (7,8) GROUP BY player1_id
UNION ALL
SELECT COUNT(current_record)*10 AS subpoints, player1_id, player2_id FROM db WHERE category_id IN (1,2,3,4,5,6) GROUP BY player1_id
) AS hi
GROUP BY player1_id
Sample table:
category_id | player1 | player2 | subpoints |
-------------+---------+---------+-----------+
7 | Tom | Mike | 2 |
5 | Peter | Tom | 10 |
----------------------------------------------
Final result should be:
Player | hiscore |
-------+---------+
Tom | 12 |
Mike | 2 |
Peter | 10 |
You can unpivot the columns first and then aggregate it:
select player, sum(subpoints) hiscore
from
(
select category_id, player1 player, subpoints
from db
union all
select category_id, player2 player, subpoints
from db
) d
group by player;
See SQL Fiddle with Demo.
If you integrate your original query into this, then the code will be similar to this:
select player, sum(subpoints) hiscore
from
(
SELECT COUNT(current_record)*2 AS subpoints, player1_id as player
FROM db
WHERE category_id IN (7,8)
GROUP BY player1_id
UNION ALL
SELECT COUNT(current_record)*10 AS subpoints, player2_id as player
FROM db
WHERE category_id IN (1,2,3,4,5,6)
GROUP BY player2_id
) d
group by player