Update a column based on the highest value from another column - mysql

I have a SQL-database with a table called 'PP_Match' with a couple of columns in it.
ID, Position_1, Position_2, Round and Draw_size
In this table ID, Position_1 and Position_2 is a composite key together!
I want to update the Draw_size column, based upon the highest value in column 'Round'. To make this extra fun, the Draw_size column should display a knock-out draw (Elimination Draw), that you use in any kind of sport.
So if the highest value in Round for a specific ID is 1, then I want to display '2' in Draw_size. If the highest value is 2 then draw_size is 4, and a 3 in Round column would return a 8 in draw_size and so on (4=16, 5=32, 6=64, 7=128).
I want to update all rows of a specific ID.
Let say that ID 001 has 5 rows in the database with the higest value in "Round" as 3, then I want to update all the 5 rows with a Draw_size value of 8...
I've tried and failed multiple times...
Thank you guys for your assitance!!!
/ Fred

Something like that should work
UPDATE PP_MATCH pp1
LEFT JOIN (
SELECT ID, MAX(ROUND) as Max_Round FROM PP_MATCH GROUP BY ID) A
ON A.ID = pp1.ID
SET pp1.Draw_size = POW(2, Max_Round)

Related

How to add a tag based on a column value

I'm trying to join two tables and select certain columns to display in the output including a 'flag' if a certain transaction amount is greater than or equal to 100. The flag would return a 1 if it is, else null.
I thought I could achieve this using a CASE in my SELECT but it only returns one record every time since it returns the first record that meets this condition. How do I just create this 'FLAG' column during my join easily?
SELECT payment_id, amount, type,
CASE
WHEN amount >= 100 THEN 1
ELSE NULL
END AS flag
FROM trans JOIN customers ON (user_id = cust_id)
JOIN bank ON (trans.bank = bank.id)
WHERE (error is false)
I expect an output such as:
payment_id amount type flag
1 81 3 NULL
2 104 2 1
3 150 2 1
4 234 1 1
However, I'm only getting the first record such as:
payment_id amount type flag
2 104 2 1
I tried your table structure in my local and it is working perfectly.
I need one thing from you is in which table you are having error column.
If I comment where condition then it is working fine.
If you're getting fewer rows than you expect, it's either due to:
Join condition
You're doing a INNER joins to the customers and bank tables. If you have 4 source rows in your trans table, but only one row that matches in your customers table (condition user_id = cust_id), then you will only have one row returned.
The same goes for the subsequent join to your bank table. If there you somehow have a transaction that references a bank which is not defined in the bank table, then you won't see a record for this row.
WHERE clause
Obviously you won't see any rows that don't meet the conditions specified here.
It's probably #1 -- check to see if the rows with payment_id IN (1,3,4) have corresponding user id values in the user table and corresponding bank id values in the banks table.

Selecting multiple same value rows out of the same column

I have a table, where one of the columns is named mid. It has a lot of values, some of them repeat themselves. Theres also a column named chashrate. It has a different value for each mid row. Theres also a column named pid, which shows the id of each row.
I've tried pulling out specific value rows with HAVING, but I can only do one value at a time or multiple values that dont match each other
$miner = $pdo->query("SELECT * FROM data WHERE pid='6'")->fetchall();
What I need to do is collect all the same MID column value rows, with the id pid=6 so for example all of the mid = 8; pid=6, collect their chashrate and sum it up. So for example I would get mid(8)=17394, mid(6)=28424 etc.
Here's a photo of the table: https://i.imgur.com/9xX6sYm.png
The same colored rows need to be selected and their chashrate values summed up.
Try using SUM to sum the cashrate values and GROUP BY to group them by mid.
SELECT mid
, SUM(`cashrate`) AS total
FROM `data`
WHERE pid = 6
GROUP BY mid;
Check it here.
For the given data on the image, this query will output the following result:
mid | total
6 | 981
8 | 374
You seem to want aggregation:
select mid, sum(chashrate) as sum_chashrate
from data
where pid = 6
group by pid, mid;
This will return multiple rows, one for each mid value.
You can do this for multiple pids -- or even all of them, by removing or changing the where clause.

SQL Validate a column with the same column

I have the following situation. I have a table with all info of article. I will like to compare the same column with it self. because I have multiple type of article. Single product and Master product. the only way that I have to differences it, is by SKU. for example.
ID | SKU
1 | 11111
2 | 11112
3 | 11113
4 | 11113-5
5 | 11113-8
6 | 11114
7 | 11115
8 | 11115-1-W
9 | 11115-2
10 | 11116
I only want to list or / and count only the sku that are full unique. follow th example the sku that are unique and no have variant are (ID = 1, 2, 6 and 10) I will want to create a query where if 11113 are again on the column not cout it. so in total I will be 4 unique sku and not "6 (on total)". Please let me know. if this are possible.
Assuming the length of master SKUs are 5 characters, try this:
select a.*
from mytable a
left join mytable b on b.sku like concat(a.sku, '%')
where length(a.sku) = 5
and b.sku is null
This query joins master SKUs to child ones, but filters out successful joins - leaving only solitary master SKUs.
You can do this by grouping and counting the unique rows.
First, we will need to take your table and add a new column, MasterSKU. This will be the first five characters of the SKU column. Once we have the MasterSKU, we can then GROUP BY it. This will bundle together all of the rows having the same MasterSKU. Once we are grouping we get access to aggregate functions like COUNT(). We will use that function to count the number of rows for each MasterSKU. Then, we will filter out any rows that have a COUNT() over 1. That will leave you with only the unique rows remaining.
Take that unique list and LEFT JOIN it back into your original table to grab the IDs.
SELECT ID, A.MasterSKU
FROM (
SELECT
MasterSKU = SUBSTRING(SKU,1,5),
MasterSKUCount = COUNT(*)
FROM MyTable
GROUP BY SUBSTRING(SKU,1,5)
HAVING COUNT(*) = 1
) AS A
LEFT JOIN (
SELECT
ID,
MasterSKU = SUBSTRING(SKU,1,5)
FROM MyTable
) AS B
ON A.MasterSKU = B.MasterSKU
Now one thing I noticed from you example. The original SKU column really looks like three columns in one. We have multiple values being joined with hypens.
11115-1-W
There may be a reason for it, but most likely this violates first normal form and will make the database hard to query. It's part of the reason why such a complicated query is needed. If the SKU column really represents multiple things then we may want to consider breaking it out into MasterSKU, Version, and Color or whatever each hyphen represents.

Count number of row results for a row group

How do I group/filter rows and then get total rows for each column. I am going to diagram what the result should be. I don't want to show the actual data. Just the count per column
Out Put should look like this
Column A Column B Column C
Row A - 235 records 300 records 15 records
Row B - 1 record 80 records 900 records
Each column represent a count on the same field but filtered.
So ..
Column A is really Count(MyColumn) WHERE = A
Column B is really Count(MyColumn) WHERE = B
To summarize each row is a grouping + filter and each column is a count based on the number of rows contained in that grouping. No row data needs to be displayed.
You can do this in a table in the group by using the following formula:
=SUM(IIF(Fields!MyColumn.Value = "A", 1, 0))
However, this type of summary report is what a matrix is designed to do. Use the Row field as the row group, the column field as the column group and a Count expression in the intersection and it will do it all for you.

SELECT unique values and the associated timestamp without having the timestamp making things unique

I apologize for the poorly worded question. It's best illustrated through an example and what I've come up with so far:
Table "myInfo" has columns:
1. id (PK)
2. key
3. value
4. metaId
Table "meta" has columns:
1. id (PK)
2. metaName
3. metaValue
4. instanceNum
metaId in the "myInfo" table correlates to a instanceNum in the "meta" table. The value of the "value" column changes sometimes over different rows with the metaId. Think of the metaId as a link to a timestamp value in the "meta" table("timestamp" and its value would go into the metaName and metaValue columns respectively).
I want to select the distinct values of the 'value' column in "myInfo". So far I have:
SELECT DISTINCT mi.key, mi.value
FROM myInfo as mi JOIN metadata as meta
WHERE mi.metaId=meta.instanceNum
AND meta.key = 'timestamp'
AND mi.key='maxWeight';
But I ALSO want the timestamps associated with those values. So I want the output to look something like:
key value timestamp
maxWeight 10 tons 15:00:05 2011-01-01
maxWeight 5 tons 08:00:07 2011-10-12
maxWeight 25 tons 13:05:09 2013-08-01
I can't place timestamp as one of the columns in my SELECT because then it will return duplicate mi.attrValue values too since the timestamp makes every row unique. I tried putting the DISTINCT keyword behind only mi.attrValue but I got a MySQL error.
This is completely untested but grouping by a concat might work.
SELECT mi.key, mi.value, meta.value
FROM myInfo as mi JOIN metadata as meta ON mi.metaId = meta.id
WHERE mi.key = 'maxWeight'
AND meta.key = 'timestamp'
GROUP BY CONCAT(mi.key, mi.value)
Although you'll still have the problem of which timestamp is shown. For example, if you have 3 records for a given key/value pair, which record will be shown in your result set?
key value timestamp
maxWeight 10 tons 15:00:05 2011-01-01
maxWeight 10 tons 08:00:07 2011-10-12
maxWeight 10 tons 13:05:09 2013-08-01
The group by query will show just one of these results - but which? You'll need to think about ordering a group (which is a whole new ballgame)
SELECT mi.key, mi.value, min(meta.value)
FROM myInfo as mi JOIN metadata as meta
WHERE mi.metaId=meta.instanceNum
AND meta.key = 'timestamp'
AND mi.key='maxWeight'
group by mi.key,mi.value
Would get you what you want with the earliest timestamp value.