How to generate this SQL query like pivot table - php

I want to three table union to one query like a pivot table.
My main table name is products and two support tables name are code_keys and code_values
I have a main table name: products
+------------------+
| Field |
+------------------+
| productid |
| catpath |
| da |
| l0 |
| ig |
| des |
| notes |
| wire |
| lmm |
+------------------+
example data:
+-----------+------+------+------+
| productid | da | ig | des |
+-----------+------+------+------+
| 5 | 78 | 33 | 23 |
| 8 | 88 | 13 | 21 |
+-----------+------+------+------+
and 2 conf table names: code_keys. Store code structure.
+--------+
| Field |
+--------+
| codeid |
| title |
| codekey|
| format |
+--------+
example data:
+--------+----------------+
| codeid | title |
+--------+----------------+
| 2 | St Code |
| 3 | Rear Les |
+--------+----------------+
code_values
+-------+
| Field |
+-------+
| id |
| pid | -> Product ID
| codeid|
| value |
+-------+
and finally example data:
+----+------+--------+--------------+
| id | pid | codeid | value |
+----+------+--------+--------------+
| 9 | 5 | 2 | ST 102 200 R |
| 10 | 5 | 3 | 12 000 33 |
| 11 | 6 | 2 | ST 343 432 R |
| 12 | 6 | 3 | 34 343 24 |
| 15 | 8 | 2 | ST 100 101 R |
| 16 | 8 | 3 | 11 223 34 |
| 17 | 0 | 2 | ST 343 432 R |
| 18 | 0 | 3 | 34 343 24 |
+----+------+--------+--------------+
I want to show like this into one query:
Product Columns | *code_keys rows > columns* |
+-----------+------+------+------+--------------+----------+
| productid | da | ig | des | St Code | Rear Les |
+-----------+------+------+------+--------------+----------+
| 5 | 78 | 33 | 23 | ST 102 200 R | 12 000 33|
| 8 | 88 | 13 | 21 | ST 100 101 R | 11 223 34|
+-----------+------+------+------+--------------+----------+
Any ideas?

You can do this using CASE statement:
SELECT p.productid, p.da, p.ig, p.des
,GROUP_CONCAT(CASE WHEN ck.title = 'St Code'
THEN cv.value ELSE NULL END) AS 'St Code'
,GROUP_CONCAT(CASE WHEN ck.title = 'Rear Les'
THEN cv.value ELSE NULL END) AS 'Rear Les'
FROM Products p
JOIN code_values cv ON p.productid = cv.pid
JOIN code_keys ck ON cv.codeid = ck.codeid
GROUP BY p.productid;
If you have unknown number of code_keys you can try this dynamic query:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'GROUP_CONCAT(CASE WHEN `title` = ''',
`title`,
''' THEN cv.value ELSE NULL END) AS `',
`title`, '`'
)
) INTO #sql
FROM code_keys ck JOIN code_values cv ON cv.codeid = ck.codeid;
SET #sql = CONCAT('SELECT p.productid, p.da, p.ig, p.des, ', #sql,'
FROM Products p
JOIN code_values cv ON p.productid = cv.pid
JOIN code_keys ck ON cv.codeid = ck.codeid
GROUP BY p.productid
');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Output:
| PRODUCTID | DA | IG | DES | ST CODE | REAR LES |
--------------------------------------------------------
| 5 | 78 | 33 | 23 | ST 102 200 R | 12 000 33 |
| 8 | 88 | 13 | 21 | ST 100 101 R | 11 223 34 |
See this SQLFiddle

Related

How to get unique parts number with their brands in mysql query?

I have below tables in my database, I want to get unique part numbers and with their brand name.
All these below tables are based on EAV Model
Table 1 for Part number (for ex - 8004).
entity_id is unique constraint
select * from catalog_product_entity_varchar where attribute_id = 961 and value = '8004';
+-----------+----------------+--------------+----------+-----------+-------+
| value_id | entity_type_id | attribute_id | store_id | entity_id | value |
+-----------+----------------+--------------+----------+-----------+-------+
| 19507400 | 10 | 961 | 0 | 39214 | 8004 |
| 19507401 | 10 | 961 | 0 | 281155 | 8004 |
| 19507402 | 10 | 961 | 0 | 1926249 | 8004 |
| 64825324 | 10 | 961 | 0 | 11892287 | 8004 |
| 168417193 | 10 | 961 | 0 | 22721887 | 8004 |
+-----------+----------------+--------------+----------+-----------+-------+
Table 2 for Brand Code -
select * from catalog_product_entity_int where attribute_id = 953 and entity_id in (39214,281155,1926249,11892287,22721887);
+----------+----------------+--------------+----------+-----------+-------+
| value_id | entity_type_id | attribute_id | store_id | entity_id | value |
+----------+----------------+--------------+----------+-----------+-------+
| 5401700 | 10 | 953 | 0 | 39214 | 1050 |
| 5401701 | 10 | 953 | 0 | 281155 | 1109 |
| 5401702 | 10 | 953 | 0 | 1926249 | 1082 |
| 21106883 | 10 | 953 | 0 | 11892287 | 1109 |
| 87135500 | 10 | 953 | 0 | 22721887 | 1109 |
+----------+----------------+--------------+----------+-----------+-------+
Table 3 for actual brand name based on brand codes.
select * from eav_attribute_option_value where option_id in (1050,1109,1082);
+----------+-----------+----------+------------------------+
| value_id | option_id | store_id | value |
+----------+-----------+----------+------------------------+
| 15222 | 1050 | 0 | Samsung |
| 13070 | 1082 | 0 | Whirlpool |
| 15317 | 1109 | 0 | GE |
+----------+-----------+----------+------------------------+
Expected Output -
I think this is the query you are looking for
SELECT GROUP_CONCAT(b.entity_id SEPARATOR ',') as entity_ids,p.value as part_no,GROUP_CONCAT(b.value SEPARATOR ',') as brand_code, GROUP_CONCAT(bn.value SEPARATOR ',') as brand_name FROM catalog_product_entity_varchar p RIGHT JOIN catalog_product_entity_int b ON p.entity_id = b.entity_id LEFT JOIN eav_attribute_option_value bn ON b.value = bn.option_id WHERE p.attribute_id = '961' GROUP BY b.entity_type_id

Symfony rank mysql database

I am actually having loads of trouble trying to obtain the rank or position of a specific row on Symfony.
Example: player table
id - name - total
1 xxxx 100
2 yyyy 200
3 www 500
When I do the following thing on the terminal, it works fine:
SELECT id, total, name, #curRank := #curRank + 1 AS rank FROM player p, (SELECT #curRank := 0) q ORDER BY total DESC
+----+-------+----------------+------+
| id | total | name | rank |
+----+-------+----------------+------+
| 19 | 1931 | guitouman | 1 |
| 2 | 1765 | lu | 2 |
| 1 | 1583 | Seyaa | 3 |
| 17 | 1532 | coucou lapinou | 4 |
| 11 | 1494 | the moine eau | 5 |
| 7 | 1446 | alien | 6 |
| 3 | 1415 | Saiyya | 7 |
| 50 | 1231 | dfdf | 8 |
| 20 | 1230 | Jrm | 9 |
| 16 | 1221 | Ragnar | 10 |
| 6 | 1182 | arachati | 11 |
| 8 | 1025 | momo | 12 |
| 10 | 789 | kingrom | 13 |
| 13 | 777 | le seur | 14 |
| 53 | 743 | aaa | 15 |
| 14 | 568 | Rakhamo | 16 |
| 9 | 466 | sapeur coco | 17 |
| 12 | 446 | chamboul | 18 |
| 51 | 321 | sdfdsf | 19 |
| 54 | 132 | | 20 |
| 52 | 46 | sdfsdf | 21 |
| 48 | 0 | dragma | 22 |
+----+-------+----------------+------+
The probleme is to get this working in Symfony2 where the "#" or "Set" keyword is not recognized. I have tried this :
$query -> $this->_em->createQuery('SET #rownum := 0;SELECT id, total, rank FROM SELECT #rownum := #rownum + 1 AS rank, id, totalTroopRecieved FROM clan ORDER BY total;')->setParameter('id', $this->getId());
return $query->getResult();
Which gives this error:
[Syntax Error] line 0, col 24: Error: Expected IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | "(" Subselect ")" | CaseExpression, got '#'
I feel desperate .. Spending 2 days for this when i know it works via sql queries but not on symfony makes me mad ..
I tried NUMBER_ROW() or RANK() function but it does not seem to work on Mysql.
Thank you for your precious help.

My query returns single record when use sum function

I have following table structure, and relationship is one purchase_order has many purchase_order_detail and one purchase_order_detail has many delivery_order;
purchase_order
+-------------------+-------------------------+
| purchase_order_id | purchase_order |
+-------------------+-------------------------+
| 29 | Dell Computer 000001256 |
| 31 | Dell Computer 000001257 |
+-------------------+-------------------------+
purchase_order_detail
+--------------------------+-------------------+---------+------------------+
| purchase_order_detail_id | purchase_order_id | item_id | ordered_quantity |
+--------------------------+-------------------+---------+------------------+
| 26 | 29 | 279 | 100 |
| 27 | 29 | 286 | 100 |
| 28 | 29 | 287 | 100 |
| 29 | 31 | 279 | 75 |
| 30 | 31 | 286 | 85 |
+--------------------------+-------------------+---------+------------------+
delivery_order
+-------------------+--------------------------+-------------------+
| delivery_order_id | purchase_order_detail_id | recieved_quantity |
+-------------------+--------------------------+-------------------+
| 30 | 26 | 50 |
| 31 | 27 | 50 |
| 32 | 28 | 50 |
| 33 | 29 | 25 |
| 34 | 30 | 35 |
+-------------------+--------------------------+-------------------+
i want to get purchase_order and total recieved quantity for a item_id in purchase_order_detail table,
i write this query,, but it returns incorrect record
SELECT po.created_on, po.purchase_order_id, po.purchase_order, i.item_name, SUM( do.recieved_quantity ) AS quantity
FROM purchase_order po, purchase_order_detail pod, delivery_order do , item i
WHERE i.item_id = pod.item_id
AND po.purchase_order_id = pod.purchase_order_id
AND pod.purchase_order_detail_id = do.purchase_order_detail_id
AND pod.item_id =286
+---------------------+-------------------+-------------------------+-----------+----------+
| created_on | purchase_order_id | purchase_order | item_name | quantity |
+---------------------+-------------------+-------------------------+-----------+----------+
| 2015-02-23 13:49:40 | 29 | Dell Computer 000001256 | Lenovo | 85 |
+---------------------+-------------------+-------------------------+-----------+----------+
as you can see that item_id 286 is against two purchase_orders.
You miss the group by clause:
SELECT po.created_on, po.purchase_order_id, po.purchase_order, i.item_name, SUM( do.recieved_quantity ) AS quantity
FROM purchase_order po, purchase_order_detail pod, delivery_order do , item i
WHERE i.item_id = pod.item_id
AND po.purchase_order_id = pod.purchase_order_id
AND pod.purchase_order_detail_id = do.purchase_order_detail_id
AND pod.item_id =286
group by po.created_on, po.purchase_order_id, po.purchase_order, i.item_name

Mysql select distinct id's and select first row only

This is my table. I want to select distinct 'bill_no' with only first related row.
+--------------+--------------+-------+------------+
| id | bill_no | product_name | tax | total |
+--------------+-------+------+-------+------------+
| 1 | 12 | Hairgel | 10 | 241 |
| 2 | 12 | Spiker gel | 10 | 300 |
| 3 | 13 | Wokzem amba | 12 | 450 |
| 4 | 13 | test prod | 1 | 145 |
| 5 | 14 | wokk | 3 | 55 |
| 6 | 14 | Kamer hyp | 11 | 46 |
| 7 | 15 | Xyombokx | 2 | 220 |
+--------------+-------+------+-------+------------+
I want data to be displayed like the below table having only distinct "bill_no" -
Output-
+--------------+--------------+-------+------------+
| id | bill_no | product_name | tax | total |
+--------------+-------+------+-------+------------+
| 1 | 12 | Hairgel | 10 | 241 |
| 3 | 13 | Wokzem amba | 12 | 450 |
| 5 | 14 | wokk | 3 | 55 |
| 7 | 15 | Xyombokx | 2 | 220 |
+--------------+-------+------+-------+------------+
Use group by
select * from youtable group by bill_no
select t1.*
from your_table t1
join
(
select min(id) as id
from your_table
group by bill_no
) t2 on t1.id = t2.id
You can use GROUP BY clause.GROUP BY clause always return first row with related group by cloumn name.
SELECT * FROM `table_1` group by `bill_no`

fetch data from multiple tables

I have 4 table for my Ads Portal.
Firstly main table name is ads
+-------------+
| Field +
+-------------+
| id +
| ads_title +
+-------------+
example data for ads table;
+----+-----------------+
| id | ads_title |
+----+-----------------+
| 20 | 2006 CITROEN C4 |
| 27 | EMEKLI OGRETMEN |
| 28 | Harika 10 n |
| 34 | HATASIZ BOYASIZ |
| 49 | BAYANDAN 2009 |
+----+-----------------+
for ads specifications stored in a table. table name is ads_spc
+---------+
| Field |
+---------+
| id |
| key_name|
+---------+
data example for ads_spc table;
+----+-------------+
| id | key_name |
+----+-------------+
| 1 | Date |
| 2 | Km |
| 3 | Colr |
| 4 | Engine |
| 5 | Pw. Engine |
| 6 | Oil |
| 7 | Speed |
| 8 | Boody Type |
| 9 | Traction |
| 10 | Warranty |
+----+-------------+
Lastly stored specification values for ads_spc by ads_id. table name is ads_values
+------------+
| Field |
+------------+
| id |
| ads_id |
| spc_id |
| value |
+------------+
for example this table data
+----+--------+--------+-------+
| id | ads_id | spc_id | value |
+----+--------+--------+-------+
| 25 | 49 | 9 | 2119 |
| 26 | 49 | 10 | 2131 |
| 27 | 34 | 1 | 2010 |
| 28 | 34 | 2 | 8900 |
| 29 | 34 | 3 | 4 |
| 30 | 34 | 4 | 22 |
| 31 | 34 | 5 | 40 |
| 32 | 34 | 6 | 60 |
| 33 | 34 | 7 | 65 |
| 34 | 34 | 8 | 66 |
+----+--------+--------+-------+
I want to using these tables list ads (table: ads) with specifications (table:ads_spc) and ads values (table:ads_values) in a data row.
Union to;
ADS + ADS_SPC + ADS_VALUES (All values searchable)
I'm using this case:
SELECT SQL_CALC_FOUND_ROWS
*
FROM ads AS a
LEFT JOIN ads_spc AS aspc
LEFT JOIN ads_values AS aval ON aval.ads_id=a.id AND aval.spc_id=aspc.spc_id
How can I union to one row?
Sorry for my english.
Why union there is no sense for the union you should join these tables
SELECT v.id, a.ads_title,s.key_name,v.value FROM `ads` a
INNER JOIN `ads_values` v ON (a.id =v.ads_id)
INNER JOIN `ads_spc` s ON(v.spc_id =s.id) WHERE s.key_name='Color'

Categories