I am having problems to figure out, how to make a pivot table with php/mysql.
There is no Code now, its mor to understand how it works.
Lets say i have a Table with packages
Table packages
pack_ID pack_Name
1 ABC
2 XYZ
3 DEF
and so on
Then a Table with Items which are part of the packages
Table items
item_ID item_Name
1 red item
2 blue item
3 green item
4 black item
And a Table to mix them
Table item-pack
pack_ID item_ID
1 2
1 4
2 1
2 3
3 2
3 4
3 3
3 1
And the result should be a pivot table
item/ pack
ABC XYZ DEF
red Item x x
blue Item x x
green Item x x
black Item x x
First i would QUery the Packages with:
SELECT p.pack_ID, p.pack_Name FROM packages
Which should give me and array with the packages.
Then i would run a for each or while and query the items like this
SELECT i.item_ID, i.item_Name FROM item-pack ip
JOIN item i ON i.item_ID = ip.item_ID
WHERE ip.pack_ID = $ValueFromThe QUery
But how the heck do i retun the result as a pivot?
is this so dificult with php?
Thy for any help.
Related
I'm trying to join a few tables in MySQL. Our setup is a little unique so I try to explain as good as I can.
I have a table 'INVENTORY' that represents the current items on stock.
These items are stored in a table 'COMPONENT'
Components are being used in installations.
Every user can have multiple installations and the same component can be used in multiple installation as well.
To uniquely map a component to an installation, it can be assigned to a PRODUCT. a product as has a 1-1 relationship with an installation. A component is not directly related to an installation
To finally assign a product to a specific installation a mapping table COMPOMENT_PRODUCT is used.
Example:
A component is like a part, lets say a screw. This screw is used in a computer. The very same screw can be used on multiple computers. But each computer can only be used on one specific installation.
TABLE COMPOMENT_PRODUCT
COMPOMENT_ID PRODUCT_ID
1 1
1 2
2 1
2 2
So we have the components C1 and C2 relevant for two installations.
TABLE INVENTORY
COMPOMENT_ID INSTALLATION_ID ON_STOCK
1 1 5
1 2 2
What I want to achieve
Now, I want to retrieve the inventory state for all components. But, not every component has an inventory record. In these cases, the ON_STOCK value from the inventory shall be NULL
That means, for this example I'd expect the following results
COMPOMENT_ID PRODUCT_ID ON_STOCK
1 1 5
1 2 2
2 1 NULL
2 2 NULL
But executing this query:
SELECT DISTINCT
COMPONENT_PRODUCT.COMPONENT_ID,
COMPONENT_PRODUCT.PRODUCT_ID,
INVENTORY.ON_STOCK
FROM INVENTORY
RIGHT JOIN COMPONENT_PRODUCT ON COMPONENT_PRODUCT.COMPONENT_ID =
INVENTORY.COMPONENT_ID
returns the following resultset:
COMPONENT_ID PRODUCT_ID ON_STOCK
1 1 5
1 2 5
1 1 2
1 2 2
2 1 (null)
2 2 (null)
Now, my next thought was, "of course, this is how joins behave, okay I need to group the results". But the way SQL works, the aggregation is not entirely predictable. SO when I
GROUP BY COMPONENT_PRODUCT.COMPONENT_ID,COMPONENT_PRODUCT.PRODUCT_ID
I get this result:
COMPONENT_ID PRODUCT_ID ON_STOCK
1 1 5
1 2 5
2 1 (null)
2 2 (null)
I have prepared a Fiddle here: http://sqlfiddle.com/#!9/71ca87
What am I forgetting here? Thanks in advance for any pointers.
Try this query -
SELECT DISTINCT
COMPONENT_PRODUCT.COMPONENT_ID,
COMPONENT_PRODUCT.PRODUCT_ID,
INVENTORY.ON_STOCK
FROM INVENTORY
RIGHT JOIN COMPONENT_PRODUCT ON COMPONENT_PRODUCT.COMPONENT_ID =
INVENTORY.COMPONENT_ID
AND COMPONENT_PRODUCT.PRODUCT_ID = INVENTORY.INSTALLATION_ID
i was trying to solve a problem which just looks like the code written below, but from lack of knowledge and reading through the sqlalchemy documentation, i do not really find any solution on how to solve my problem, yet.
Objective:
Get summed value of sales_in_usd if year in year_column is same
What I got so far is by debugging and reading a bit through stackoverflow and documentations, google by using following query:
session.query(fact_corporate_sales, Company, Sales,
Time, Sector, func.sum(Sales.sales_in_usd).label('summary')).\
join(Sales).\
join(Time).\
join(Company).\
join(Segment).\
order_by(Time.year.desc()).\
filter(Company.company_name.like(filtered)).\
group_by(fact_corporate_sales.fact_cps_id, Company.company_name,fact_corporate_sales.cps_id).\
all()
And well the fact_cps_id is unique in the fact_table and the same table stores, the keys of the dimension tables as well..
I have a fact table which stores 4 foreign keys from 4 dimension tables.
fact_cps_id company_id sales_id time_id sector_id
1 4 2 1 2
2 4 1 1 3
3 4 3 2 1
4 4 2 2 4
5 4 4 3 2
6 4 99 1 1
dim_company
company_id company_name
1 Nike
2 Adidas
3 Puma
4 Reebok
dim_segment
segment_id segment_nom
1 basketball
2 running
3 soccer
4 watersports
dim_time
time_id quarter year
1 1 2013
2 2 2013
3 1 2014
4 3 2014
dim_sales
sales_id sales_in_euro
1 2000
2 3200
3 1400
4 1590
.. ..
99 1931
So basically, as you can see in the table and query what I was trying to do was summing up all sales from the as example dim_Time.year <- from the same year.
If we look into the fact_table we can see, that we have time_id = 1 three times, here. So those values could be summed up and displayed as a summary.
I know from standard SQL that it was possible by using group by and aggregate function sum.
My result(time_id is only for help therefore was no output):
13132.0 <- time_id = 1
21201.0 <- time_id = 2
23923.0 <- time_id = 1
31232.0 <- time_id = 99
32021.0 <- time_id = 2
32342.0 <- time_id = 1
131231.0 <- time_id = 4
I printed the actual query into the console and got this [had to remove .all(), because 'list' has no attribute called 'statement']:
SELECT fact_corporate_sales.cps_fact_id, fact_corporate_sales.cps_id,
fact_corporate_sales.company_id, fact_corporate_sales.time_id, fact_corporate_sales.segment_id, sum(dim_corporate_sales.sales_in_usd) AS summary
FROM fact_corporate_sales INNER JOIN dim_corporate_sales ON dim_corporate_sales.cps_id = fact_corporate_sales.cps_id INNER JOIN dim_time ON dim_time.time_id = fact_corporate_sales.time_id INNER JOIN dim_company ON dim_company.company_id = fact_corporate_sales.company_id INNER JOIN dim_segment ON dim_segment.segment_id = fact_corporate_sales.segment_id
WHERE dim_company.company_name LIKE %s GROUP BY fact_corporate_sales.cps_fact_id ORDER BY dim_time.year DESC
And if I want to group by for example dim_time.Year only..I get following response from mysql or console
Error Code: 1055. Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'db.fact_corporate_sales.fact_cps_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
The solution was only to execute following sql:
engine.execute("SET sql_mode='';")
As the response of my failed query was:
"this is incompatible with sql_mode=only_full_group_by"
I had to disable the sql_mode and so did I and got my result.
select multiple rows on nested condition and nested limit in mysql database
Actually i have one table like:
id name levels
1 Red 1
2 Red Light 1
3 Green 2
4 Green Light 2
5 Blue 3
6 Blue Light 3
7 Blue Dark 3
I want fetch any rows according to levels with any limits Like:
From Level-1 = 1 row
From Level-2 = 2 row
From Level-3 = 2 row
total rows are 5 according to levels.
Any one know about single query is possible?
or
three foreach loop will be implement?
I have a table named (Products) and 2 column named Apple(A) and Grape(G). Each fruit as value of 1's. I want a query which will count all the 1's under each column and display it with total count under each fruit.
A G
1 1
1 1
I want output to show like below (Horizontally or Vertically)
Apple
2
Grape
2
Select count(Apple) as 'Apple', count(Grape) as 'Grape' from products
Table 1:Domain Link Result
======================================================================
||Column1(words) ||Column2(links) ||Column3(frequency) ||
======================================================================
1 1 Any Number
2 1 Any Number
3 1 Any Number
4 1 Any Number
1 2 Any Number
2 2 Any Number
3 2 Any Number
4 2 Any Number
Table 2:Sub Link Result
======================================================================
||Column1(words) ||Column2(sublinks) ||Column3(frequency) ||
======================================================================
1 a Any Number
2 b Any Number
3 c Any Number
4 d Any Number
1 e Any Number
2 f Any Number
3 g Any Number
4 h Any Number
And so on.
In the above scenario user entered 4 words and 2 domain links. Now the frequency of 4 keywords is calculated on domain links as well sublinks and stored in separate tables as shown above. I want an aggregate result like below:
Table 3:Final Result
==================================================================================
||Column1(words) ||Column2(Domain links) ||Column3(Total frequency) ||
==================================================================================
Row1: 1 1 Total of frequency in both tables
2 for word "1"
----------------------------------------------------------------------------------
Row2: 2 1 Total of frequency in both tables
2 for word "2"
----------------------------------------------------------------------------------
Row3: 3 1 Total of frequency in both tables
2 for word "3"
----------------------------------------------------------------------------------
Row4: 4 1 Total of frequency in both tables
2 for word "4"
----------------------------------------------------------------------------------
I tried the following query in MySQL:
SELECT t.`keyword`, t.`link` SUM( t.`frequency` ) AS total
FROM (
SELECT `frequency`
FROM `domain_link_result`
WHERE `keyword` = 'national'
UNION ALL
SELECT `frequency`
FROM `sub_link_result`
WHERE `keyword` = 'national'
)t GROUP BY `keyword`
But in Column 2 of the final result I get only first link instead of two links for row 1. How can I get both links or any number of links entered by user in a single row ?
Words and Links have VARCHAR as type and frequency has INT type.
If you want to collapse several rows into one and still be able to see the information, you have to use GROUP_CONCAT
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
This outputs the collapsed values separated by commas, i.e.: a string. In your programming language you can split this string if you need individual values.
Your query would look somehow like this
SELECT keyword, GROUP_CONCAT(links), SUM(frequency)
FROM (subquery)
GROUP BY keyword
Which would output something like this:
==================================================================================
||Column1(words) ||Column2(Domain links) ||Column3(Total frequency) ||
==================================================================================
Row1: 1 1,2 sum of freq.
----------------------------------------------------------------------------------
Row2: 2 1,2 sum of freq.
----------------------------------------------------------------------------------
Row3: 3 1,2 sum of freq.
----------------------------------------------------------------------------------
Row4: 4 1,2 sum of freq.
EDIT: Extra help for your query
Your query looks a little bit confusing to me. Try with a JOIN approach:
SELECT domain_link_results.word AS word,
GROUP_CONCAT(domain_link_results.links) AS domain_links,
domain_link_results.frequency + sub_link_results.frequency AS total_frequency
FROM domain_link_results
INNER JOIN sub_link_results
ON domain_link_results.word = sub_link_results.word
WHERE domain_link_results.word = "national"
GROUP BY domain_link_results.word
On the other hand, it might be better to have all the links in the same table, and an extra field to determine if it's a domain link or a sublink. Without knowing more about your system it is hard to say.