I have 3 tables like the tables below
tbl_GasExpense
GID | Gas_Expense | Date_Occured
-----------------------------------
1 | 400 | 11/30/2014
2 | 500 | 11/30/2014
3 | 300 | 11/30/2014
tbl_Food Expense
FID | Food_Expense | Date_Occured
-----------------------------------
1 | 450 | 11/30/2014
2 | 250 | 11/30/2014
3 | 390 | 11/30/2014
tbl_Drink Expense
DID | Drink_Expense | Date_Occured
-----------------------------------
1 | 150 | 11/30/2014
2 | 250 | 11/30/2014
3 | 360 | 11/30/2014
and with those tables above, I want an output like this.
ID | Gas_Sum | Food_Sum | Drink_Sum | Date_Occured
-----------------------------------------------------------
1 | 1200 | 1090 | 760 | 11/30/2014
The values of the three tables from which are dated 11/30/2014 are summed in table four.
Using the IDs from the first three tables as foreign keys in the table 4 to establish a relation. Gas_Sum is a mask for GID, Food_Sum for FID, Drink_Sum for DID.
Thanks guys, but I already have my answer now after several trial and errors
.. it is something like this. but this is on my own code
SELECT o.eh_ID, SUM(o.others_amt) as 'OTHERS SUM'
FROM tbl_Others o
INNER JOIN tbl_ExpenseHead hd ON hd.eh_ID = o.eh_ID
GROUP BY o.eh_ID
Related
I have a mySQL database table containing cellphones information like this:
ID Brand Model Price Type Size
==== ===== ===== ===== ====== ====
1 Apple A71 3128 A 40
2 Samsung B7C 3128 B 20
3 Apple ZX5 3128 A 30
4 Huawei Q32 2574 B 40
5 Apple A21 2574 A 25
6 Apple A71 3369 A 30
7 Samsung A71 7413 C 40
Now I want to create another table, that would contain counts for every possible combination of the parameters.
Params Count
============================================== =======
ALL 1000000
Brand(Apple) 20000
Brand(Apple,Samsung) 40000
Brand(Apple),Model(A71) 7100
Brand(Apple),Type(A) 6000
Brand(Apple),Model(A71,B7C),Type(A,B) 7
Model(A71) 12514
Model(A71,B7C) 26584
Model(A71),Type(A) 6521
Model(A71),Type(A,B) 8958
Model(A71),Type(A,B),Size(40) 85
And so on for every possible combination. I was thinking about creating a stored procedure (that i would execute periodically), that would perform queries with every existing condition like that, but I am a little stuck on how exactly should it look like. Or is there a better way how to do this?
Edit: the reason why I want to store information like this is to be able to show number of results in filter in client application, like in the picture.
I would like to create index on the Params column to be able to get the Count number for given hash instantly, improving performance.
I also tried querying and caching the values dynamically, but I want to try this approach as well, so I can compare which one is more effective.
This is how I am calculating the counts now:
SELECT COUNT(*) FROM products;
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple');
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple', 'Samsung');
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple') AND Model IN ('A71');
etc.
You can use a ROLLUP for this.
SELECT
model, type, size, COUNT(*)
FROM mytab
GROUP BY 1, 2, 3
WITH ROLLUP
With your sample data, we get the following:
| model | type | size | COUNT(*) |
| ----- | ---- | ---- | -------- |
| A21 | A | 25 | 1 |
| A21 | A | | 1 |
| A21 | | | 1 |
| A71 | A | 30 | 1 |
| A71 | A | 40 | 1 |
| A71 | A | | 2 |
| A71 | C | 40 | 1 |
| A71 | C | | 1 |
| A71 | | | 3 |
| B7C | B | 20 | 1 |
| B7C | B | | 1 |
| B7C | | | 1 |
| Q32 | B | 40 | 1 |
| Q32 | B | | 1 |
| Q32 | | | 1 |
| ZX5 | A | 30 | 1 |
| ZX5 | A | | 1 |
| ZX5 | | | 1 |
| | | | 7 |
The subtotals are present in the rows with null values in different columns, and the total is the last row where all group by columns are null.
I have several categories that I need to store in a database and present them to users. Each one has a minimum of three to a maximum of four ranges. E.g.:
id | category_name | Range A | Range B | Range C | Range D
--------------------------------------------------------------------
1 | Category1 | 0 - 200 | 200 - 450 | 450 - 750 | 750+
2 | Category2 | 0 - 300 | 300 - 600 | 600+ |
3 | Category3 | 0 - 250 | 250 - 350 | 350 - 550 | 550+
When an user picks a category, he should then select a certain range that will be saved in the database.
name | category_id | category_range
------------------------------------------
niceuser30 | 2 | A
hellouser1 | 1 | B
Considering that:
ranges cannot have gaps between them (e.g. if range A goes from 100 to 200, range B must start from 200)
each range must start from 0
each range must be open ended (or half-open)
What would be the best design for a table to hold these values?
I was thinking of using something akin to this
id | category_name | range_a | range_b | range_c | range_d
-------------------------------------------------------------
1 | Category1 | 1500 | 3000 | 5000 | 5000
2 | Category2 | 500 | 1000 | 1000 |
and then elaborate the output before serving it to the user (if two ranges are equal the code sets the last one "ad infinitum", so the first one would be "0 - 1500, 1500 - 3000, 3000 - 5000, 5000+") but it seems dirty and prone to errors.
you could use 2 table e.g Ranges:
id | RangeName| Start | End | Range |
--------------------------------------------------------------------
1 | A | 0 | 1500 | 1500 |
2 | B | 1500 | 3000 | 1500 |
3 | C | 3000 | 4000 | 1000 |
....
and RangeCategories:
id | CategoryID|RangeId|
--------------------------------------------------------------------
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 3 |
4 | 2 | 1 |
.....
And of course you will also have your categories Table:
id | CategoryName|...
--------------------------------------------------------------------
1 | Category1 | ...
2 | Category2 | ...
3 | Category3 | ...
i have a table 'house' with a house id, a table 'room' with a room id, and a relation table for those two tables
HOUSE
-----
1 | house1
2 | house2
3 | house3
4 | house4
5 | house5
ROOM
------
1 | kitchen
2 | bathroom
3 | garage
HOUSE_ROOMS
------------
id | house_id | room_id | size
=================================
1 | 1 | 1 | 200
2 | 1 | 2 | 300
3 | 2 | 1 | 400
4 | 2 | 2 | 500
5 | 3 | 1 | 500
6 | 4 | 2 | 600
7 | 5 | 1 | 400
8 | 5 | 5 | 300
I'm having trouble writing a query that returns an array of house id's by some combined conditions:
example: get all houses with a kitchen sized between 350 and 450 AND a bathroom sized between 450 and 550
-> result should be an array containing house2
anyone know how i should write this query?
Assuming all your IDs are fixed, the following quick query will work:
SELECT HOUSE_ID
FROM HOUSE_ROOMS
WHERE (ROOM_ID=2 AND SIZE>=450 AND SIZE<=550)
OR (ROOM_ID=1 AND SIZE>=350 AND SIZE<=450)
GROUP BY HOUSE_ID
HAVING COUNT(DISTINCT ROOM_ID)>1
TABLE 'styles'
id|style_code
1|6110
2|6120
3|6250
TABLE 'colour'
id|colour_code
1|1001
2|1012
3|1033
4|1050
TABLE 'styleColour'
id|style_id|colour_id|cancelled
1 | 1 | 1 |
2 | 1 | 2 | y
3 | 2 | 1 |
4 | 2 | 3 |
5 | 2 | 4 |
6 | 3 | 1 |
7 | 3 | 2 |
8 | 3 | 3 | y
9 | 3 | 4 | y
TABLE 'orders'
id|style_code|colour_code
1 | 6110 | 1001
2 | 6110 | 1012
3 | 6130 | 1001
4 | 6130 | 1033
5 | 6130 | 1050
6 | 6250 | 1033
7 | 6250 | 1050
Output wanted (based on 'order' table):
style_code|colour_code|cancelled
6110 | 1001 |
6110 | 1012 | y
6130 | 1001 |
6130 | 1033 |
6130 | 1050 |
6250 | 1033 | y
6250 | 1050 | y
What joins are needed to reference the 'cancelled' column to the appropriate style_code and colour_code combination on the 'order' table ouput?
Please bear in mind that although it may seem odd that the 'style_code' and 'colour_code' data as shown rather than being represented by style_id and colour_id, this is required for importing reasons.
Thanks and kind regards,
Derek.
Updated answer as per comments below -
SELECT orders.style_code,orders.colour_code,styleColour.cancelled
FROM orders
LEFT JOIN colours ON orders.colour_code=colours.colour_code
LEFT JOIN styles ON orders.style_code=styles.style_code
LEFT JOIN styleColour ON styleColour.style_id=styles.id
AND styleColour.colour_id=colours.id;
However if you make the JOINs on colours/styles being on the id column instead of the code column (I assume id is the primary key), it might be faster (as primary keys are indexed).
This is my attempt at that. I haven't tested it, but give it a try:
SELECT orders.style_code,orders.colour_code,styleColour.cancelled
FROM styleColour
RIGHT JOIN colours ON orders.colour_id=colours.id
RIGHT JOIN styles ON orders.style_id=styles.id
RIGHT JOIN orders ON orders.style_code=styles.style_code
AND orders.colour_code=colours.colour_code;
The reason it's all RIGHT JOINs is to do all the joining based on the rows in orders as opposed to styleColour.
I have two mysql tables: earning and redemption. Data in the earning table adds to a running balance and data in the redemption table subtracts from that balance. Each table has an hours column and an amount column.
(There are various reasons why these aren't negative and positive values in the same table, but even with these reasons I recognize now that this is likely a poor schema design, but... for now I'm stuck with it).
How can I get a current balance for both the hours and amounts fields? More specifically, how can I write a single query that will give me SUM(earning.hours) - SUM(redemption.hours) and SUM(earning.amount) - SUM(redemption.amount), grouped by a Common_ID?
Some sample data. Other fields exist in each table, but I'm not concerned with them at the moment.
Earning:
+----+-----------+-------+--------+
| id | common_id | hours | amount |
+----+-----------+-------+--------+
| 1 | 234 | 1.03 | 15.75 |
| 2 | 234 | 2.06 | 33.00 |
| 3 | 237 | 2.11 | 12.29 |
| 4 | 237 | 3.50 | 18.63 |
+----+-----------+-------+--------+
Redemption:
+----+-----------+-------+--------+
| id | common_id | hours | amount |
+----+-----------+-------+--------+
| 1 | 234 | 2.50 | 30.00 |
| 2 | 234 | 0.50 | 5.68 |
| 3 | 237 | 1.00 | 8.00 |
+----+-----------+-------+--------+
Desired result:
+-----------+---------------+----------------+
| common_id | hours_balance | amount_balance |
+-----------+---------------+----------------+
| 234 | 0.09 | 13.07 |
| 237 | 4.61 | 22.92 |
+-----------+---------------+----------------+
You need to perform the grouping separately.
SELECT e.Common_ID,
SUM(e.hours) - MIN(g.SumHours),
SUM(e.amount) - MIN(g.SumAmount)
FROM earning e JOIN (
SELECT Common_ID, SUM(hours) SumHours, SUM(amount) SumAmount
FROM redemption
GROUP BY Common_ID
) g ON e.Common_ID = g.Common_ID
GROUP BY Common_ID
Note: as Lamak pointed out, if you have an common_id that doesn't exists in both tables, you will need a LEFT JOIN and possibly another UNION with a RIGHT JOIN.