I have two tables called transdt and inv_sldtl.
The transdt table consists of the customer ID and the total price of the items that customers bought.
+----------+-----------+-----------+------------+------------+----------+
| BranchID | TransCode | ControlNo | CustomerID | Date | Amount |
+----------+-----------+-----------+------------+------------+----------+
| 1 | 48 | 469 | 1170 | 2017-05-01 | 295.00 |
| 1 | 48 | 469 | 1185 | 2017-05-01 | 44257.24 |
+----------+-----------+-----------+------------+------------+----------+
and the inv_sldtl contains the item id, unit cost, quantity and total cost.
+----------+-----------+--------+-----------+------------+----------+----------+-----------+
| BranchID | TransCode | ItemID | ControlNo | Date | Quantity | UnitCost | TotalCost |
+----------+-----------+--------+-----------+------------+----------+----------+-----------+
| 1 | 48 | 108 | 469 | 2017-05-01 | 1.00 | 45.00 | 45.00 |
| 1 | 48 | 736 | 469 | 2017-05-01 | 10.00 | 25.00 | 250.00 |
| 1 | 48 | 622 | 469 | 2017-05-01 | 4.00 | 280 | 1120.00 |
| 1 | 48 | 500 | 469 | 2017-05-01 | 4.00 | 10784.31 | 43137.24 |
| | | | | | | | |
+----------+-----------+--------+-----------+------------+----------+----------+-----------+
Given that the results of two tables are in same one transaction which is determined by the ControlNo.
Is there any way we can output like this?
+-----------+-----------+------------+--------+------------+
| ControlNo | TransCode | CustomerID | ItemID | Date |
+-----------+-----------+------------+--------+------------+
| 469 | 48 | 1170 | 108 | 2017-05-01 |
| 469 | 48 | 1170 | 736 | 2017-05-01 |
| 469 | 48 | 1185 | 622 | 2017-05-01 |
| 469 | 48 | 1185 | 500 | 2017-05-01 |
+-----------+-----------+------------+--------+------------+
I assume that we can determine it based on the Amount in transdt table and TotalCost in inv_sldtl table. But how?
EDIT: Since SQL seems doesn't have a solution for this, How can I achieve this using VB6 as my programming language as what #ThorstenKettner have told?
Thanks :)
You would have to build all item combinations in order to compare these with the customers' totals.
pack #1 | pack #2 | sums
-----------+------------+-----------------
item 1 | item 2+3+4 | 45.00 , 44507.24
item 1+2 | item 3+4 | ...
item 1+3 | item 2+4 | ...
item 1+4 | item 2+3 | ...
item 1+2+3 | item 4 | ...
item 2 | item 1+3+4 | ...
item 2+3 | item 1+4 | ...
...
This is no task for SQL. At least not for a DBMS that doesn't support recursive queries. So use a programming language instead. I.e. use Java, C#, whatever, read the data, then get your totals by calling a recursive function.
UPDATE: You have asked for further help on the algorithm. Here is one possible way:
You have a set of n customers, here (1170,1185).
You have a set of m items, here (108,500,622,736).
Take the customer with the lowest total, here customer 1170 with 295.00.
Find item combinations matching the price. You'd use a recursive function call and stop as soon as the price is too high. So you quickly end up with item 108 = 45.00, item 736 = 250.00 and items 108+736 = 295.00. Only the last combination is a match.
Remove the customer from the cusomer set. Remove the item(s) from the item set.
Continue with step 3, till you are done.
To make this a tad more complicated: You see that you can have multiple matches for a customer, e.g. both items A + B and items B + C + D match the customer total. So step 5 and following must be done for every match. Another recursion :-)
Do this slowly, step by step, so as not to get confused. Good luck :-)
Without knowing exactly what you want and if you have Primary or Foreign keys which if you don't should have your ControlNo in first table transdt the PK and FK in your inv_sldt1 so that you can use something like my code below. This way you can also link the tables together by some column. Anyways again without seeing everything here is what I came up with on the fly check it out and let me know.
SELECT CustomerID, Date, Quantity
FROM transdt
INNER JOIN inv_sldt1 ON transdt.ControlNo=inv_sldt1.ControlNo
WHERE ItemID = 108
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 would like to ask for a help.I use MySQL 5.7 and I have a Bill of Materials table called BOM.
I have many columns there which I will add later to the query, but for this questionID, Name, ParentID and Quantity is important. I would like to add a calculated column totalQty to my table that will multiply children quantities with parent quantities up to the top level. here is an example of what I want to achive:
+-------+------+------+----------+----------+--+
| ID | Name | Qty | ParentID | TotalQty | |
+-------+------+------+----------+----------+--+
| 1 | A | 1 | 0 | 1 | |
| 1.1 | AA | 2 | 1 | 2 | |
| 1.1.1 | AAA | 1 | 1.1 | 2 | |
| 1.2 | AB | 5 | 1 | 5 | |
| 1.2.1 | ABA | 2 | 1.2 | 10 | |
| 2 | B | 3 | 0 | 3 | |
| 2.1 | BA | 2 | 2 | 6 | |
+-------+------+------+----------+----------+--+
I need this to create a list of materials used per project, so I will multiply totalQTY with unit mass and unit length to get total mass and total length of part. Then I will group and aggregate them by material type.
I have searched the forums, and I have found out that I need to use Common table expressions (CTE) for this. But I have found no explanation in plain english on how to do it for my case.
Thank you very much for any help or hint how to understand the concept.
I am unable to successfully write this query and have not yet found any resources.
I have a table with two columns. The table looks a bit like this:
|student|teacher|
| 5314 | 656 |
| 4189 | 671 |
| 4506 | 671 |
| 4515 | 671 |
| 3754 | 756 |
| 3760 | 756 |
| 1066 | 781 |
I want the result set to look like this:
|teacher|count|
| 656 | 1 |
| 671 | 3 |
| 756 | 2 |
| 781 | 1 |
Any hint is really appreciated.
You want to use the COUNT(*) aggregate function here, and group by the teacher column.
Try this:
SELECT teacher, COUNT(*) as numStudents
FROM myTable
GROUP BY teacher;
This will group all rows from your table by teacher, and count the number of rows in that group (effectively counting the number of students).
Here is more on Aggregate Functions for you.
I am writing a program in java to fetch records from infobright database. Here are the table structure, query and the format of output I require.
Table structure:
column name type
------------ ----------
id integer
date integer
product_id integer
search_engine_id integer
visitor integer
example query:
select date,
product_id,
search_engine_id,
sum(visitor)
from report
where date in (201300910, 20130919)
group by search_engine_id,
product_id,
date
order by product_id,
date
The result set of the above query would be in the following format:
+----------+-------------+----------------+------------------+
| date | product_id | search_engine_id | sum(visitor) |
+----------+-------------+----------------+------------------+
| 20130910 | 108 | 2 | 7 |
| 20130910 | 108 | 1 | 15 |
| 20130919 | 108 | 1 | 2 |
| 20130919 | 108 | 2 | 3 |
| 20130910 | 107 | 1 | 3 |
| 20130910 | 107 | 2 | 2 |
| 20130919 | 107 | 1 | 2 |
| 20130919 | 107 | 2 | 3 |
| 20130919 | 106 | 1 | 10 |
There are two types of search_engine_id, that is 1 and 2.
For a given day, one product_id can exist two times at max, i.e., one record for search_engine_id 1 and other record for search_engine_id 2. What I want is to group the result with respect to product_id. So it would look something like:
+-------------------+-------------+----------------+------------------+
| date | product_id | search_engine_id | sum(visitor) |
+-------------------+-------------+----------------+------------------+
| 20130910,20130919 | 108 | 2,1,1,2 | 7,15,2,3 |
The main reason of doing this in the sql side is to make the data prepared for every product_id so that it will have less memory usage in java side. I have tried group_contact function but that seems to be not supported by infobright. Is there a way I can rewrite the query/make use of some other function to achieve this?
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.