Query results depends on result from seperate query - php

What's the most effective way to go about querying the table to output the results as shown?
Table:
+-----+----------+-----+
| PN | date | QTY |
+-----+----------+-----+
| AB1 | 01/12/14 | 4 |
| AB2 | 01/12/14 | 2 |
| AB3 | 01/12/14 | 7 |
| AB1 | 01/22/14 | 8 |
| AB3 | 01/25/14 | 3 |
| AB5 | 01/25/14 | 9 |
+-----+----------+-----+
Results:
+-----+----------+----------+----------+
| | 01/12/14 | 01/22/14 | 01/25/14 |
+-----+----------+----------+----------+
| AB1 | 4 | 8 | 0 |
| AB2 | 2 | 0 | 3 |
| AB5 | 7 | 0 | 9 |
+-----+----------+----------+----------+

What you want to do is called pivoting the data. It can be achieved in MySQL with some CASE statements and aggregate functions.
E.G.
SELECT PN,
SUM(CASE WHEN date='20141201' THEN qty END) AS day1Qty,
SUM(CASE WHEN date='20141202' THEN qty END) AS day2Qty
FROM table
GROUP BY PN
Of course you'll likely want to do something to dynamically handle the dates that are being aggregated so it isn't just a static list (unless that is what you're after).
See these answers for more info:
Pivot Table Using MySQL
MySQL pivot table

Related

SQL query with in clause and get data with subsequent order according to name column

I am not sure if it is asked before, but the problem is like this.
+---------+---------------+------+-----------+
| item_id | name | data |priority | expire |
+---------+---------------+------+-----------+
| 11 | decimal_queue | data| 0 | 0 |
+---------+---------------+------+------+----+
Now, There are different type of queue, in the name decimal_queue, single_queue, three_queue, I want to get them one by one in SELECT query with limit of lets;s say 10
So, first let's suppose item of decimal_queue then the next item single_queue then three_queue in this manner, also I want to limit total number to max 10 and the queue can be dynamic in number.
Is it achievable, I am also using PHP in backend, if that also solves to get array like that.
I tested - but not sure is it achievable, if yes - how to approach this
You can use a CTE to create a ROW_NUMBER() window function and create a limit for your rows in a WHERE clause:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS rn
FROM queues)
SELECT
item_id,
name,
data,
priority,
expire
FROM cte
WHERE rn <= 10
ORDER BY rn, name
Result:
| item_id | name | data | priority | expire |
|---------|---------------|------|----------|--------|
| 11 | decimal_queue | data | 0 | 0 |
| 12 | single_queue | data | 2 | 1 |
| 13 | three_queue | data | 0 | 0 |
| 14 | decimal_queue | data | 3 | 0 |
| 16 | single_queue | data | 0 | 0 |
| 15 | three_queue | data | 1 | 1 |
| 17 | decimal_queue | data | 3 | 1 |
| 19 | single_queue | data | 0 | 1 |
| 20 | three_queue | data | 3 | 0 |
| 18 | decimal_queue | data | 2 | 0 |
| 21 | single_queue | data | 0 | 1 |
| 22 | three_queue | data | 2 | 1 |
| 23 | decimal_queue | data | 1 | 0 |
| 24 | single_queue | data | 1 | 0 |
Demo here.
You can also reverse the order (or specify any order you like) by using the FIELD function instead of name in your ORDER BY:
ORDER BY rn, FIELD(name,'three_queue','single_queue','decimal_queue')
Demo here.

SQL Query - display join result in one result row [duplicate]

This question already has answers here:
Can I concatenate multiple MySQL rows into one field?
(16 answers)
MySQL DISTINCT on a GROUP_CONCAT()
(6 answers)
Closed 4 years ago.
I want to create an advanced search based on one table and other tables
my tables:
estate :
+------+-------------+-------------------+-------------------+
| id | title | cat_id | date |
+------+-------------+-------------------+-------------------+
| 1 | test1 | 1 | 1526793203 |
| 2 | test2 | 2 | 1526793203 |
| 3 | test3 | 3 | 1526793203 |
+------+--------------+------------------+-------------------+
estate_risk
+------+-------------+----------------+--------------+
| id | estate_id | title | consequence |
+------+-------------+----------------+--------------+
| 3 | 1 | risktitle1 | 123 |
| 4 | 1 | risktitle2 | 433 |
| 5 | 1 | risktitle3 | 523 |
| 6 | 2 | risktitle4 | 976 |
| 7 | 2 | risktitle5 | 422 |
| 8 | 3 | risktitle6 | 124 |
+------+-------------+----------------+--------------+
related_estate
+------+-------------+----------------+--------------+
| id | estate_id | title | storage |
+------+-------------+----------------+--------------+
| 3 | 1 | testdata | 1 |
| 4 | 1 | testdata2 | 2 |
| 5 | 1 | testdata3 | 3 |
| 6 | 2 | testdata4 | 4 |
| 7 | 2 | testdata5 | 5 |
| 8 | 5 | testdata6 | 6 |
+------+-------------+----------------+---------------+
And some other tables...(foreign all tables is estate_id)
I want to get all the data in a row,in other words for example, I have several related data in the estate_risk table and when I use join query get this result data :
sample query one join:
SELECT R.id,R.title,C.title,C.storage FROM estate R LEFT JOIN estate_risk as C ON estate_risk .estate_id = R.id
result :
----------+------------------+----------------+--------------+
R.id | R.title | C.title | C.consequence
----------+------------------+----------------+--------------+
1 | test1 | risktitle1 | 123 |
1 | test1 | risktitle2 | 433 |
1 | test1 | risktitle3 | 523 |
2 | test2 | risktitle4 | 976 |
2 | test2 | risktitle5 | 422 |
3 | test3 | risktitle6 | 124 |
----------+------------------+----------------+--------------+
Everything is right but i want get all the data in a row that's mean only a row R.id with all C.title in one row
My main goal is to display the page search results just one estate with all other data tables
+------+-------------+----------------+----------------+
id | estate_title| estate_risk | related_estate |
+------+-------------+----------------+----------------+
1 test1 risktitle1 testdata1
risktitle2 testdata2
risktitle3 testdata3
---------------------------------------------------------
2 ...
Maybe my goal is not right, but I do not know how I can get this output And this should be done on the database side, or programming side ?
What ideas can be made on the programming side?
It looks like what you want is a GROUP_CONCAT to put together the risktitles and related_estates.
GROUP_CONCAT(C.title SEPARATOR '\n'),
GROUP_CONCAT(Some_other_column SEPARATOR '\n')
Once you have your group functions, I believe grouping by R.id as Yanet suggested and the data should come together correctly.
If you do have larger data sets though, there are limitations to MySQL's concatenation functions. So in that case you might need to return the data as you are already and then reformat it to match what you want in the PHP side.
Group Concat Limit

MySQL group rows by one column sorting by another column

I'm developing a PHP script, and I have the following table:
+----+-----------+----------+--------------+
| id | id_parent | position | feature |
+----+------------+---------+--------------+
| 1 | 1 | 2 | -B-A-C- |
| 2 | 1 | 3 | -B-C- |
| 3 | 2 | 4 | -C-B- |
| 4 | 3 | 1 | -A-B- |
| 5 | 1 | 6 | -A-C- |
| 6 | 2 | 5 | -C-B- |
| 7 | 2 | 7 | -B-C- |
| 8 | 3 | 8 | -A- |
+----+-----------+----------+--------------+
From this table I would like to select all the rows with "feature" LIKE "%-A-%", but displaying first the result with lowest "position", then all the rows that have same value for column "id_parent" of the first result, then row with the 2nd lowest "position" and all the rows that have same "id_parent" of the result with the 2nd lowest "position", and so on...
So the final result should be:
+----+-----------+----------+--------------+
| id | id_parent | position | feature |
+----+------------+---------+--------------+
| 4 | 3 | 1 | -A-B- |
| 8 | 3 | 8 | -A- |
| 1 | 1 | 2 | -B-A-C- |
| 5 | 1 | 6 | -A-C- |
+----+-----------+----------+--------------+
For some reason I can't explain here I need to have and HAVING clause for selecting the right "feature" value (...HAVING 'feature' LIKE '%-A-%' ...).
Is it possible to make all this with MySQL (possibly without subqueries) or by processing data results with PHP?
Does this help? I've left the last part of the problem as an exercise for the reader...
SELECT a.*
, c.*
FROM my_table a
JOIN
( SELECT id_parent, MIN(position) position FROM my_table WHERE feature = 'a' GROUP BY id_parent ) b
ON b.id_parent = a.id_parent
AND b.position = a.position
JOIN my_table c
ON c.feature = a.feature
AND c.id_parent = a.id_parent;

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

PHP and MYSQL select with 5 tables and multiple rows as a single array

Would like to get the following as a result from the table structure below (MYSQL + PHP)
array[0][name]1,[desc]red,[title]hero,[desc]strong,[desc2]smells,[img][0]red1,[img][1]red2,[img][2]red3,ext[0].jpg,[ext][1].gif,[ext][2].png,[count][0]253,[count][1]211,[count][2]21,[count][3]121,[dist][0]5,[dist][1]5,[dist][2]12,[dist][3]2,[score][0]2,[score][1]3,[score][2]1,[score][3]5,[score][4]4,[val][0]5,[val][1]1,[val][2]4,[val][3]3,[val][4]4
The problem I have with a simple SELECT, JOIN and GROUP_CONCAT is that the values duplicate after selecting all the images.
I've tried various other ways for example selecting the data by row combined with a foreach loop in PHP, but I end up with lots of duplicates, and it looks very messy.
I also though about splitting it into multiple selects instead of using one, but I really would like to know if it can be done with one select.
Could someone help me with an MYSQL select? Thanks
game
+-----+----------+
| pid | name |
+-----+----------+
| 1 | red |
| 2 | green |
| 3 | blue |
+-----+----------+
detail
+-----+------+--------+-------+--------+
| id | pid | title | desc | desc 2 |
+-----+------+--------+-------+--------+
| 1 | 1 | hero |strong | smells |
| 2 | 2 | prince |nice | tall |
| 3 | 3 | dragon |big | green |
+-----+------+--------+-------+--------+
image
+-----+-----+-----+----+
| id | pid | img |ext |
+-----+-----+-----+----+
| 1 | 1 | red1|.jpg|
| 2 | 1 | red2|.gif|
| 3 | 1 | red3|.png|
+-----+-----+-----+----+
devmap
+-----+-----+-------+------+
| id | pid | count | dist |
+-----+-----+-------+------+
| 1 | 1 | 253 | 5 |
| 2 | 1 | 211 | 5 |
| 3 | 1 | 21 | 12 |
| 4 | 1 | 121 | 2 |
+-----+-----+-------+------+
stats
+-----+-----+-------+------+
| id | pid | scrore| val |
+-----+-----+-------+------+
| 1 | 1 | 2 | 5 |
| 2 | 1 | 3 | 1 |
| 3 | 1 | 1 | 4 |
| 4 | 1 | 5 | 3 |
| 5 | 1 | 4 | 3 |
+-----+-----+-------+------+
When you do a JOIN that involves more than a 1:1 mapping between tables you're going to have duplicate data, and there's no way to get around that in the query.
You can break it out into multiple selects, or you can loop through the result set and pare out whatever duplicate information you don't want.

Categories