get table information using feching table in mysql stored procedure - php

Help....
I have 2 tables,
customers
id | registration_code | full_name
1 | A01 | ABC
2 | B01 | BCD
3 | C01 | CDE
4 | D01 | DEF
history_transaction
id | customer_id | transaction_date
1 | 1 | 2015-01-01
2 | 2 | 2015-01-01
3 | 3 | 2015-01-01
4 | 1 | 2015-01-02
5 | 3 | 2015-01-02
6 | 1 | 2015-01-03
I use PHP, and I want to get a customer list and transaction times between 2015-01-01 till 2015-01-03
the result should be
id | registration_code | full_name | n_trans
1 | A01 | ABC | 3
2 | B01 | BCD | 1
3 | C01 | CDE | 2
Please help. I want to use Store Procedure on MySQL, and I dont want to loop it in PHP.

To get the info you use a group by statement:
SELECT a.id,a.registration_code,a.full_name, COUNT(*) as n_trans
FROM customers a
INNER JOIN history_transaction b
ON a.id=b.customer_id
WHERE b.transaction_date BETWEEN "{start_date}" AND "{end_date}"
GROUP BY a.id,a.registration_code,a.full_name;
You can set start_date and end_date dynamically using mysqli (a php module for working with MySQL from php).

This is the way to create stored procedure in MySQL:
CREATE PROCEDURE find_transaction_detail()
BEGIN
SELECT a.id,a.registration_code,a.full_name, COUNT(*) as n_trans
FROM customers a
INNER JOIN history_transaction ON a.id=b.customer_id
WHERE b.transaction_date BETWEEN "{start_date}" AND "{end_date}"
GROUP BY a.id,a.registration_code,a.full_name;
END;
Way to find result:
CALL find_transaction_detail ();

Related

Confusing about group and having clause with php

I need to get all IDs from table A where all the Expiry date from Table B (INNER JOIN ID = A_ID) are < today (2018-06-29) but i'm not sure and a bit confusing for the query.
Based on my example (2018-06-29) i need to retrieve only Name-4 because ALL Expiry date from Table B are < 2018-06-29
Table A
ID | Name |
-------------
1 | Name-1
2 | Name-2
3 | Name-3
4 | Name-4
5 | Name-5
6 | Name-6
7 | Name-7
Table B
ID | A_ID | Expiry
-----------------------
1 | 1 | 2018-06-29
2 | 2 | 2018-07-29
3 | 2 | 2018-06-29
4 | 3 | 2018-07-29
5 | 3 | 2018-04-29
6 | 4 | 2018-05-29
7 | 4 | 2018-04-29
8 | 6 | 2018-09-29
9 | 6 | 2018-10-29
You are correct that you need both the GROUP BY and the HAVING clauses. Since you require that all expiry dates for a matching A_ID are less than a given date, you must check the MAX() expiry for that grouping.
SELECT ta.* FROM tableA ta JOIN tableB tb ON ta.ID = tb.A_ID
GROUP BY ta.id
HAVING MAX(Expiry) < '2018-06-20';
DEMO

how to calculate unique column values in mysql

Here is my data
cardNo| userName| tablename| hours | date
1 | a | a | 12 | 12-06-2015
1 | a | a | 5 | 11-06-2015
2 | b | b | 3 | 15-06-2015
1 | a | a | 8 | 12-06-2015
2 | b | b | 3 | 21-06-2015
1 | a | a | 12 | 14-06-2015
2 | b | b | 10 | 8-06-2015
cardNo is unique. I need to display all details and total hours for each card, like:
cardNo | userName | tablename | totalhours
1 | a | a | 37
2 | b | b | 16
It's simple SUM() with GROUP BY:
SELECT cardNo,sum(hours)
FROM yourtable
GROUP BY cardNo;
I left it as an exercise for the OP to include userName and tablename columns into the query
SELECT cardNo,userName, tablename, sum(hours) hours
FROM Table_1 GROUP BY cardNo,userName,tablename

how to count the mysql data when match rules

I would like to do a show how many promotion code left function.
I already find out how to query the latest promotion. now i would like to show the code how many left.
Now I have 2 table,
this is t1.
+--------------+--------------------------+----------------------+
| id | name | description |
+--------------+--------------------------+----------------------+
| 1 | GG | GG is good |
| 2 | ABC DEFG | ABC DDDDD |
| 3 | CCARD | Gooooo |
+--------------+--------------------------+----------------------+
this is t2
+---------+------------+-------------------+------------------+
| id | kaid | code | timestamp |
+---------+------------+-------------------+------------------+
| 1 | 2 | ZZZZAAAAA | 123456789 |
| 2 | 2 | AAAZZADWWW | 123344444 |
| 3 | 1 | ASFASDFFFF | 123333333 |
| 4 | 2 | HHHHHFDFG | 123222222 |
| 5 | 1 | ASDASDADDDD | 123111111 |
| 6 | 1 | AAAAAAAA | |
| 7 | 1 | DGDFGDSFG | |
+---------+------------+-------------------+------------------+
I query the latest user get promotion code like this
$querylist = mysql_query("SELECT t2.*,t1.name FROM t2,t1 where t1.id = t2.kaid ORDER BY t2.timestamp desc limit 5");
while($rowlist = mysql_fetch_row($querylist)) {
$idlist[] = $rowlist['id'];
$user_list_latest[] = $rowlist;
}
After I loop query, I will get the data like this
1. GG
2. ABC DEFG
3. GG
4. ABC DEFG
5. ABC DEFG
Then I would like to show the count like this.
Hypothesis the count data is $countleft
1. GG (This promotion code only 2 left!)
2. ABC DEFG (This promotion code only 0 left!)
3. GG (This promotion code only 2 left!)
4. ABC DEFG (This promotion code only 0 left!)
5. ABC DEFG (This promotion code only 0 left!)
the number 2 and 0 is $countleft.
the t2 timestamp is means the user get the valid promotion code time. so the timestamp empty means nobody get yet.
Change your query to this and try
select name,balance from t1 join
(SELECT kaid,COUNT(ID) as balance FROM t2
WHERE isnull(timestamp) GROUP BY kaid)t3
on (kaid=t1.id) ORDER BY balance desc limit 5;
In the loop print every row and column(there is only two column for each row). It will give the answer.

Joining and Ordering two tables that have same columns

I am trying to combine these two tables then order it by one column (stamp), and aliasing the second table's id field. I've tried joins, merges, but nothing seems to work. I am also trying to group them by the mm
Table note
id | mm | stamp |
==========================
1 | 5 | 2009-12-11 |
2 | 33 | 2010-09-10 |
3 | 22 | 2011-07-08 |
4 | 1 | 2012-05-06 |
Table note_admin
id | mm | stamp |
==========================
1 | 5 | 2009-08-15 |
2 | 5 | 2011-11-11 |
3 | 5 | 2012-01-08 |
4 | 35 | 2012-02-06 |
Query I thought would work:
(SELECT * FROM note WHERE mm=5)
UNION
(SELECT id AS a_id, mm, stamp FROM note_admin WHERE mm=5)
ORDER BY stamp DESC
Expected Result
id | a_id | mm | stamp |
================================
| 3 | 5 | 2012-01-08 |
| 2 | 5 | 2011-11-11 |
1 | | 5 | 2009-12-11 |
| 1 | 5 | 2009-08-15 |
I don't even know if this is possible. I found a way to sort this in PHP but it would be much easier if it can be done in mySQL. Thanks.
I think you mean this, note the same 4 column names (not sure about the order by though):
(SELECT a_id as NULL, note.* FROM note WHERE mm=5) UNION (SELECT id AS a_id, NULL as id, mm, stamp FROM note_admin WHERE mm=5) ORDER BY stamp DESC

MYSQL Query locking up server

When trying to execute this query my mysql server cpu usage goes to 100% and the page just stalls. I setup an index on (Client_Code, Date_Time, Time_Stamp, Activity_Code, Employee_Name, ID_Transaction) it doesn't seem to help. What steps can I go about next to fix this issue? Also there is already one index on the database if that matters any. Thanks
Here is what this query does
Database info
ID_Transaction | Client_Code | Employee_Name | Date_Time |Time_Stamp| Activity_Code
1 | 00001 | Eric | 11/15/10| 7:30AM | 00023
2 | 00001 | Jerry | 11/15/10| 8:30AM | 00033
3 | 00002 | Amy | 11/15/10| 9:45AM | 00034
4 | 00003 | Jim | 11/15/10| 10:30AM | 00063
5 | 00003 | Ryan | 11/15/10 | 12:00PM | 00063
6 | 00003 | bill | 11/14/10 | 1:00pm | 00054
7 | 00004 | Jim | 11/15/10 | 1:00pm | 00045
8 | 00005 | Jim | 11/15/10| 10:00 AM| 00045
The query takes the info above and counts it like so. By the most recent entry for each client_code. In this case the query would look like this. After php.
Jerry = 1
2 | 00001 | Jerry | 11/15/10| 8:30AM | 00033
Amy = 1
3 | 00002 | Amy | 11/15/10| 9:45AM | 00034
Ryan = 1
5 | 00003 | Ryan | 11/15/10 | 12:00PM | 00063
Jim = 2
7 | 00004 | Jim | 11/15/10 | 1:00pm | 00045
8 | 00005 | Jim | 11/15/10| 10:00 AM| 00045
$sql = "SELECT m.Employee_Name, count(m.ID_Transaction)
FROM ( SELECT DISTINCT Client_Code FROM Transaction)
md JOIN Transaction m ON
m.ID_Transaction = ( SELECT
ID_Transaction FROM Transaction mi
WHERE mi.Client_Code = md.Client_Code AND Date_Time=CURdate() AND Time_Stamp!='' AND
Activity_Code!='000001'
ORDER BY m.Employee_Name DESC, mi.Client_Code DESC, mi.Date_Time DESC,
mi.ID_Transaction DESC LIMIT 1 )
group by m.Employee_Name";
Is there a better way to write this query so it doesnt bog down my system? The query works fine with 10 database entries but it locks my server up when the database has 300,000 entries.
Thanks
Eric
+----+--------------------+-------------+--------+------------------------+--------------+---------+----------------+------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------------+--------+------------------------+--------------+---------+----------------+------+----------+----------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | [NULL] | [NULL] | [NULL] | [NULL] | 8 | 100.00 | Using temporary; Using filesort |
| 1 | PRIMARY | m | index | [NULL] | search index | 924 | [NULL] | 21 | 100.00 | Using where; Using index; Using join buffer |
| 3 | DEPENDENT SUBQUERY | mi | ref | search index,secondary | search index | 18 | md.Client_Code | 3 | 100.00 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | Transaction | index | [NULL] | secondary | 918 | [NULL] | 21 | 38.10 | Using index |
+----+--------------------+-------------+--------+------------------------+--------------+---------+----------------+------+----------+----------------------------------------------+
What about going with multiple GROUP BY's instead of the all the sub queries to simplify things.... something like:
SELECT * FROM Transaction WHERE Date_Time=CURdate() AND Time_Stamp!='' AND Activity_Code != '000001' GROUP BY Client_Code, Employee_Name
If I'm understanding your query correctly then something like this would solve the issues and prevent the need for sub queries.
You'll definitely want to do a join instead of a sub select.
Also, how many records are you viewing? Is pagination and using limit out of the question?
If you set up your initial query modified with inner/outer joins as a view and it doesn't crash, you'll be one step closer. Once the view is set up, you'll be able to use a much less complicated select statement - potentially paginated.

Categories