I need to show the data from DB into a table of report file.
my_table looks like:
+----+-------+------+------+-------------------+-----------+-------+----+-------------------+
| id |entryID|userID|active| dateCreated |affiliateId|premium|free| endDate |
| 1 | 69856 | 1 | N |2014-03-22 13:54:49| 1 | N | N |2014-03-22 13:54:49|
| 2 | 63254 | 2 | Y |2014-03-21 13:35:15| 2 | Y | N | |
| 3 | 56324 | 3 | N |2014-03-21 11:11:22| 2 | Y | N |2014-02-22 16:44:46|
| 4 | 41256 | 4 | Y |2014-03-21 08:10:46| 1 | N | Y | |
| .. | ... | ... | ... | ... | ... | ... | .. | ... |
+----+-------+------+------+-------------------+-----------+-------+----+-------------------+
I need to create the table with data from my_table
| Date | № of Entries (in that date) | Total № of Entries | Premium | Free | Afiiliate |
The final table in file should looks like:
Report 17-07-2013:
+----------+--------------+-------+---------+------+-----------+
| Date | № of Entries | Total | Premium | Free | Afilliate |
|2013-07-17| 2 | 99845 | 2 | 0 | 0 |
|2013-07-18| 1 | 99843 | 0 | 1 | 0 |
|2013-07-22| 1 | 99842 | 1 | 0 | 1 |
|2013-07-23| 3 | 99841 | 2 | 1 | 2 |
|2013-07-24| 298 | 99838 | 32 | 273 | 25 |
|2013-07-25| 5526 | 99540 | 474 | 5058 | 126 |
|2013-07-26| 1686 | 94014 | 157 | 1532 | 56 |
|2013-07-27| 1673 | 92328 | 156 | 1517 | 97 |
|2013-07-28| 1461 | 90655 | 155 | 1310 | 83 |
| ... | ... | ... | ... | ... | ... |
+----------+--------------+-------+---------+------+-----------+
Should I for each column do a SELECT or I should do only 1 select?
If it possible to do 1 select how to do it?
It should be by analogy with this report:
report
Some fields differ (like 'Number of Entries in that date').
Total number of Entries means: all entries from beginning to the that specific date.
Number of Entries in that date means: all entries in that date.
In a final table the date from column Date will not repeat, that's why Column 'Number of Entries (in that date)' will calculate all entries for that date.
Your result is not so clear for the total is a count or sum and affiliate is sum or count also
but assuming total will be count and affiliate will be sum
here a query you might use to give you a result ( using ms-sql )
select DateCreated,count(EntryId) as Total,
sum(case when Premium='Y' then 1 else 0 end) as Premium,
sum(case when Premium='N' then 1 else 0 end) as Free,
sum(AffiliateId) as Affiliate
from sample
group by DateCreated
here a working demo
if I didn't understood you correctly, kindly advise
hope it will help you
SQLFiddle Demo: http://sqlfiddle.com/#!9/20cc0/5
The added column entryID does not matter for us.
I don't really understand what you want for Total, or the criteria for affiliateID. This query should get you started.
SELECT
DATE(dateCreated) as "Date",
count(dateCreated) as "No of Entries",
99845 as Total,
sum( case when premium='Y' then 1 else 0 end ) as Premium,
sum( case when premium='N' then 1 else 0 end ) as Free,
sum( case when affiliateID IS NOT NULL then 1 else 0 end) as Affiliate
FROM MyTable
GROUP BY DATE(dateCreated)
ORDER BY Date ASC
The final table in file should looks like:
... This new table can be in a file or in the web page. But it is not a new table in DB. –
It sounds like you may be new to this area so I just wanted to inform you that spitting out a report into a file for a website is highly unusual and typically only done when your data is completely separate from the website. Putting data from a database onto a website (like the query we made here) is very common and it's very likely you don't need to mess with any files.
select date(DateCreated),count(entryId) as Total,
sum(case when Premium='Y' then 1 else 0 end) as Premium,
sum(case when Premium='N' then 1 else 0 end) as Free,
sum( case when affiliateID IS NOT NULL then 1 else 0 end) as Affiliate
INTO OUTFILE '/tmp/myfile.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
from my_table
group by date(DateCreated) order by date(DateCreated);
Related
In MySQL, I have a table that holds the outcomes of rounds of a contest. This table has a result column that contains the values 'won' 'lost' or 'draw'. How can I group by the competitor and get the counts of specific values? The idea is to be able to sort competitors based on the number of wins and losses, and calculate scores within the database query.
So, my table is:
+--------------+---------+--------+
| CompetitorId | MatchId | Result |
+--------------+---------+--------+
| 1 | 1 | won |
| 2 | 1 | lost |
| 1 | 2 | won |
| 3 | 2 | lost |
+--------------+---------+--------+
The result I am trying to get is:
+--------------+------+--------+
| CompetitorId | Wins | Losses |
+--------------+------+--------+
| 1 | 2 | 0 |
| 2 | 0 | 1 |
| 3 | 0 | 1 |
+--------------+------+--------+
The query I tried was this:
SELECT CompetitorId, COUNT(result='won') AS wins, COUNT(result='lost') AS losses
FROM match_competitors
GROUP BY CompetitorId
You can use sum with a case inside, giving a value of 1 when is the column you need and 0 when is not:
SELECT CompetitorId, sum(case result
when 'won' then 1
else 0
end) as wins,
sum(case result
when 'lost' then 1
else 0
end) as losses
FROM match_competitors
GROUP BY CompetitorId
I have two predefined tolerance limits in another table(A), i want to calculate how many values which are above the tolerance limit and below the tolerance limit using 'Single Query' INTO two different variables using data in current table(B). Is it possible using single query ? There is also a very important where clause in the same query which is for non unique int column called referenceNo.
Example:
Tolerance 1 from Table A : 4
Tolerance 2 from Table A : 6
referenceNo and Data Value from Table B:
+-------------+------------+
| referenceNo | Data Value |
+-------------+------------+
| 227 | 7 |
| 227 | 2 |
| 227 | 4 |
| 227 | 5 |
| 227 | 9 |
| 228 | 5 |
| 228 | 1 |
| 228 | 0 |
| 228 | 8 |
| 228 | 6 |
+-------------+------------+
i am expecting output COUNT(*) for below Tolerance 1 and COUNT(*) for above Tolerance 2 INTO #BelowTolerance1Count and #AboveTolerance2Count.
Like:
Output: (For referenceNo = 227)
+-----------------------+-----------------------+
| #BelowTolerance1Count | #AboveTolerance2Count |
+-----------------------+-----------------------+
| 1 | 2 |
+-----------------------+-----------------------+
Output: (For referenceNo = 228)
+-----------------------+-----------------------+
| #BelowTolerance1Count | #AboveTolerance2Count |
+-----------------------+-----------------------+
| 2 | 1 |
+-----------------------+-----------------------+
Thanks in Advance.
I think the following code example will help you understand how to do this:
SELECT
referenceNo,
SUM(CASE WHEN VALUE < 4 THEN 1 ELSE 0 END) AS BELOW_4
SUM(CASE WHEN VALUE > 6 THEN 1 ELSE 0 END) AS ABOVE_6
FROM TABLE_NAME
GROUP BY referenceNo
Note: This solution solves for all reference numbers, not just a specific number. This is often how SQL works since it is set based.
You could make a view
CREATE VIEW SOLVE_PROBLEM AS
SELECT
referenceNo,
SUM(CASE WHEN VALUE < 4 THEN 1 ELSE 0 END) AS BELOW_4
SUM(CASE WHEN VALUE > 6 THEN 1 ELSE 0 END) AS ABOVE_6
FROM TABLE_NAME
GROUP BY referenceNo
And then use it
SELECT * FROM SOLVE_PROBLEM WHERE referenceNo = 227
SELECT * FROM SOLVE_PROBLEM WHERE referenceNo = 228
or even
SELECT
#BelowTolerance1Count = BELOW_4,
#AboveTolerance2Count = ABOVE_6
FROM SOLVE_PROBLEM
WHERE referenceNo = 228
I'm trying to count all the rows which has a status of checked out,
but I can only do is to populate it by rows then count it dynamically.
How can I make my rows as header then count the status after?
I need to make the dorm name rows as column header
then checked out as rows.
Query :
SELECT Room_Number as 'Room Number',Dorm_Name as 'Dorm Name',
COUNT(IF(action = 'Checked Out' , 1, NULL)) 'Checked Out' FROM billeting_history group by dorm_name;
+-----------+-------------+-------------+
| Dorm Name | Room_number | Checked Out |
+-----------+-------------+-------------+
| Arquitola | 205 | 1 |
| Hangar | 201 | 0 |
| Noble | 200 | 0 |
+-----------+-------------+-------------+
Desired output :
+-------------+-----------+--------+-------+
| Room Number | Arquitola | Hangar | Noble |
+-------------+-----------+--------+-------+
| 205 | 1 | 0 | 0 |
| 201 | 0 | 0 | 0 |
| 200 | 0 | 0 | 0 |
+-------------+-----------+--------+-------+
If you know the specific columns you want, you can use conditional aggregation:
SELECT Room_Number,
SUM( CASE WHEN Dorm_Name = 'Arquitola' THEN checked_out ELSE 0 END ) as Arquitola,
SUM( CASE WHEN Dorm_Name = 'Hangar' THEN checked_out ELSE 0 END ) as Hangar,
SUM( CASE WHEN Dorm_Name = 'Noble' THEN checked_out ELSE 0 END ) as Noble
FROM billeting_history
GROUP BY Room_Number;
If you don't know the full list of names, then you need to use dynamic SQL.
I have the following situation. I'm setting up a stock control system and through it, I control the in and out of products.
In a table I have the products (code, description).
In the other table, record the movement of the products (code, product_code, type [in, out], quantity, date).
When I try to make the calculation of what comes in, the less that comes out, it does not work.
MY QUERY:
SELECT SUM(s1.quantity) - SUM(s2.quantity)
FROM `stock_movement` AS s1
JOIN `stock_movement` AS s2
ON s1.code_product = s2.code_product
WHERE s1.type = 'IN'
AND s2.type = 'OUT';
RESULTS: 80
The correct result here should be (40 + 20) - (10 + 10) = 40, but this query is considering that all inputs are of type IN and OUT, so the result 80.
Anyone have any idea what I'm doing wrong? The table data below are as follows:
TABLE STOCK_MOVEMENT:
| CODE | CODE_PRODUCT | TYPE | QUANTITY | DATA |
| 1 | 30 | IN | 20 | 2018-01-20 |
| 2 | 30 | IN | 40 | 2018-02-03 |
| 3 | 30 | OUT | 10 | 2018-01-20 |
| 4 | 30 | OUT | 10 | 2018-02-03 |
TABLE STOCK:
| CODE | DESCRIPTION |
| 30 | TEST_PRODUCT |
You don't need to self join here, just use conditional aggregation:
SELECT
CODE_PRODUCT,
SUM(CASE WHEN TYPE = 'IN' THEN QUANTITY ELSE 0 END) -
SUM(CASE WHEN TYPE = 'OUT' THEN QUANTITY ELSE 0 END) AS diff
FROM stock_movement
GROUP BY CODE_PRODUCT;
Note that I am aggregating by product. For your particular sample data set, there is only one product, so we could remove GROUP BY and get the same result. But in practice you might want a solution which handles multiple products.
I have the following table
+-----+------------------+-------------+
| id | name |month_1 |
+-----+------------------+-------------+
| 1 | anna | 15 |
| 2 | bin | 20 |
+-----+------------------+-------------+
When I make a selection I want to add one more column.
For example
SELECT id,name, money as month_1 FROM test where month(day)='1';
And I want to add a column, something like this:
SELECT id,name, money as month_1,money as month_2
FROM test
where where month(day)='1',where month(day)='2'
+-----+------------------+-------------+------------+
| id | name | month_1 |month_2 |
+-----+------------------+-------------+------------+
| 1 |anna | 15 | 10 |
| 2 | bin | 20 | 0 |
+-----+------------------+-------------+------------+
You can use conditional aggregation:
SELECT id,name,
SUM(CASE WHEN month(day) = 1 THEN money ELSE 0 END) as month_1,
SUM(CASE WHEN month(day) = 2 THEN money ELSE 0 END) as month_2
FROM test
GROUP BY id, name;
You may or may not want to include the month and year in the aggregation.