mySQL - how to keep count() function from dropping 0 counts? - mysql

I'm new to mySQL and working on a query which essentially takes one initial table and summarizes its contents in two separate tables. The second "summary" table is dropping tuples where a value is 0; I need to fix that. Here's the specifics:
I have a large Inventory table, which I assemble from other tables:
SID CID SECTION RATING
==========================
100 1001 1 A
101 1001 1 A
102 1002 1 B
103 1002 2 F
104 1003 1 A
...etc...
("CID" and "Section" are the primary keys here, I don't know if whether the PK is spread across two attributes is significant here.) I have a successful query ("numTable1") which counts the number of SIDs for each CID and Section. For example, with the above Inventory table, "sumTable1" would be:
CID SECTION numSID
=====================
1001 1 2
1002 1 1
1002 2 1
1003 1 1
...etc...
Here's the SQL:
create temporary table numTable1(
SELECT ot1.cid, ot2.section, count(ot1.sid) 'numSID'
FROM otherTable1 ot1, otherTable2 ot2
WHERE ot1.cid=ot2.cid and ot1.section=ot2.section
GROUP BY ot1.cid, ot2.section
);
"NumTable" works great. Here's the problem: I also need a query which counts the number of 'A' Ratings per CID/Section:
create temporary table numA(
select t9.cid, t9.section, count(ot1.rating) 'As'
from otherTable1 ot1, t9
where grade = 'A' and t9.cid=ot1.cid and t9.section=ot1.section
group by t9.cid, t9.section
);
Here's the output of "numA":
CID SECTION As
=====================
1001 1 2
1003 1 1
...etc...
But here's the problem; some CID/Sections have no A Ratings, and they are being washed out. What I need is this:
CID SECTION As
=====================
1001 1 2
1002 1 0
1002 2 0
1003 1 1
...etc...
You'll note that the above table can be seamlessly merged with "numTable1", which is the ultimate aim here:
CID SECTION numSID As
==========================
1001 1 2 2
1002 1 1 0
1002 2 1 0
1003 1 1 1
But as long as "numA" drops CID/Sections with 0 As, I'm dead in the water. I assume my "group by" statement in "numA" is washing out the zeroes... but I'm not sure about that. Any suggestions?

#NigelRen provided the solution - a left join. Here's the code:
-- Left Join on numTable1 with numA... makes for total students // numAs
-- Resultant table is totA: "Total A Ratings"
create temporary table totA(
select numTable1.cid, numTable19.section, numTable1.numStudents, if(numA.As is null, 0, numA.As) 'A Ratings'
from numTable1
left join numA on numTable1.cid=numA.cid and numTable1.section=numA.section
);

Related

How to get data with condition SQL QUERY

So first of all, I have 2 table. The first one is the categories
Id Name
------------
1 Interior
2 Eksterior
3 Display
then the secon table is history which the data is the task I've finished
Id category_name category_id date (month) User Id
---------------------------------------------------------------
001 Interior 1 3 1084
002 Eksterior 2 3 1084
003 Interior 1 4 1089
004 Eksterior 2 4 1085
005 Display 3 4 1085
and what I want is to get categories by month, user id and know which one already done and not done from history, like this
example the data in March with user id 1084 :
Id Name Status
---------------------------
1 Interior done
2 Eksterior done
3 Display not done
or like this :
Id Name Status
--------------------------
1 Interior 1
2 Eksterior 1
3 Display 0
if the category in history table exist, the status will be 1 for done and 0 for not done.
this is my query before :
SELECT c.id, c.category, c.id=h.category_id status FROM categories c, history h WHERE MONTH(h.created_at)
I keep retrieving the wrong result for my query. Please help me..
Seems like:
SELECT *
FROM
categories c
LEFT JOIN history h on h.category_id = c.id AND h."date (month)" = 3
..will get you towards what you want: there will be NULL in the row from history table, for category Display; you can use this "is or is not null" to create your done/not done column

FInd missing row based on Column data -MySQL

I am currently working on a.Net web form solution which generates a brief service report for admins to monitor the services done by technicians.As of now , i am having some trouble in coming up with an efficient SQL (for MySQl) which return data rows along with the missing rows based on the SertvicePrtNum , which is in order.
For Example :-
This is my raw data in the table :-
Id ServiceRptNum Customer_ID Date of Service
---- ------------- ----------- ---------------
1 1001 3 09/10/1997
2 1003 8 10/06/2005
3 1005 1 21/02/2003
4 1007 7 1/06/2011
5 1010 4 4/11/2012
6 1002 2 16/01/2003
Here the ServiceRptNum , 1004 is missing in the table. So i want the db to return the result as : -
Id ServiceRptNum Customer_ID Date of Service
---- ------------- ----------- ---------------
1 1001 3 09/10/1997
2 1002 2 16/01/2003
3 1003 8 10/06/2005
- 1004 - -
4 1005 1 21/02/2003
- 1006 - -
5 1007 7 1/06/2011
- 1008 - -
- 1009 - -
6 1010 4 4/11/2012
Here , the sql additionally generated 1004,1006,1008,1009 since it cannot find those records.
Please note that the Id is automatically generated (auto_increment)while insert of the data.But the Service ReportNum is not , this is to enable the admin to add the service report later on with the manually generated report Num (report num in the hardcopy of the company Servicebook).
You basically need to invent a constant, sequential stream of numbers and then left join your real data to them. For this method to work, you need a table with enough rows in it to generate a counter big enough:
select ID, 1000+n as servicerptnum, customer_id, `Date of Service` from
(
SELECT #curRow := #curRow + 1 AS n
FROM somebigtable
JOIN (SELECT #curRow := 0) r
WHERE #curRow<100
) numbergen
LEFT JOIN
tablewithmissingservicerptnum
ON
servicerptnum = 1000+n
You need to alter some things in the code above because you never told us the name of your table with missing rptnums. You also need to utilise another table in your database with more rows than this table because the way this method works is to count the rows in the bigger table, giving each a number. If you don't have any table bigger than this one, we can probably get enough rows by cross joining a smaller table to itself or by using this table. Replace somebigtable with thistable CROSS JOIN thistable where this table is the name of the table with missing servicerptnums
If you want just the rows that are missing, add a WHERE servicerptnum is null to the end of the sql
Edit, I see you've changed your numbering from:
1001
1002
...
1009
10010
To:
1009
1010
The join condition used to be servicerptnum = concat('100', cast(n as varchar)), it is now servicerptnum = 1000+n..
Look here for ideas on how to generate a group of continuous integers, then select from that left outer join your table. You should get a row for every number but all the values will be null for the missing numbers.

How to use migration queries in MySQL tables for replace records?

I have some existing mysql tables.
Table 1 - lead_records
leadid leadnumber
1 98264*****
2 88952*****
3 99625*****
and so on.
Table 2 - counsellors
cid counselorid leadnumber
1 101 98264*****
2 102 88952*****
3 101 99625*****
and so on.
Now I want to change some record structure. In place of leadnumber I want to use leadid something like -
cid counselorid leadid
1 101 1
2 102 2
3 101 3
There are thousands of records already stored in that table? How can I replace leadnumber to lead id.
Add counsellors column with index:
ALTER TABLE `counsellors` ADD `leadid` INT NOT NULL, ADD INDEX (`leadid`);
Set leadid based on leadnumber:
UPDATE counsellors c SET c.leadid = (SELECT l.leadid FROM lead_records l WHERE l.leadnumber = c.leadnumber LIMIT 1);
(optional) If everything is ok, drop column:
ALTER TABLE `counsellors` DROP `leadnumber`;

MYSQL - Add multiple users to a table column

Maybe it's because I don't understand how to search for the right verbiage, but I'm having difficulty understanding how to attach multiple users to a table with multiple columns.
Here is what I'm attempting to do:
table name: user
user_id user_name
1 abc
2 xyz
3 pqr
4 new
table2 name : brackets
id user_id bracket_name
1 4,2 bracket_1
2 4,3,1 bracket_2
3 2,1 bracket_3
4 3,4,2 bracket_4
-- OR --
table name: user
user_id user_name brackets_id
1 abc 2,3
2 xyz 1,3,4
3 pqr 2,4
4 new 1,2,4
table2 name : brackets
brackets_id user_id bracket_name
1 4,2 bracket_1
2 4,3,1 bracket_2
3 2,1 bracket_3
4 3,4,2 bracket_4
I'm using nodejs and sequalize as my ORM and understand enough to read, write, delete and update to these tables, but when it comes to organizing my data, I'm completely lost!
Is it possible to add an array to MYSQL with the user ID's or the brackets that the user is allowed to access? The bracket are generated by a user and then they can invite their friends to join a bracket. Users can join multiple brackets and join other brackets as users.
Any guidance would be very helpful!
I think a Junction Table would simplify this for you: http://en.wikipedia.org/wiki/Junction_table
It would look something like:
table name: user
user_id user_name
1 abc
2 xyz
3 pqr
4 new
table2 name : brackets
brackets_id bracket_name
1 bracket_1
2 bracket_2
3 bracket_3
4 bracket_4
table3 your junction table:
user_id brackets_id
1 2
1 3
2 1
2 3
2 4
etc.etc.

Get multiple records from two tables having primary and foreign key relationship

![enter image description here][1]In the First Table tblserialnumbersprimary i have a primary field called as serialNoId ,this field is repeating multiple times in the second table tblserialnumbers. when we are inserting multiple records with that serialNoId.
I want to get Distinct records from the first table i.e tblserialnumbersprimary and corresponding multiple records from the dependent table i.e tblserialnumbers in MySQL
First Table Fields are:
tblserialnumbersprimary (serialNoId,serialPO,serialProductNo,
SerialNumberMode,serialNoAutoPrefix,serialDateOfCreation,
serialModifiedBy,serialStatus)
Second Table Fields are:
tblserialnumbers(serialId,serialNoId,
serialNo,serialNoBatchId![enter image description here][1])
I tried With This Joins Query.But its giving multiple records of first table
select * FROM tblserialnumbersprimary
LEFT OUTER JOIN tblserialnumbers
ON (tblserialnumbersprimary. serialNoId = tblserialnumbers.serialNoId )
First Table values are:
serialNoId serialPO serialProductNo SerialNumberMode serialNoAutoPrefix serialDateOfCreation serialModifiedBy serialStatus
1 PO1 PROD121 Automatic TCS-03 2/25/2014 12:00:00 AM admin 0
2 PO2 PROD345 Automatic TCS-03 2/25/2014 12:00:00 AM admin 1
3 PO5 PROD816 Automatic 2/26/2014 12:00:00 AM admin 1
4 PO1 PROD121 Automatic GTS-03 2/26/2014 12:00:00 AM admin 1
Second Table values are:
serialId serialNoId serialNo serialNoBatchId
1 1 TCS-03-PROD121-1 batch1
2 1 TCS-03-PROD121-2
3 1 TCS-03-PROD121-3 batch3
4 1 TCS-03-PROD121-4
5 1 100
6 1 101
1 2 TCS-03-PROD345-1 batch1
2 2 TCS-03-PROD345-2
3 2 TCS-03-PROD345-3 batch3
4 2 TCS-03-PROD345-4
1 3 --1
2 3 --2
3 3 --3
4 3 --4
5 3 12
6 3 13
7 3 11
1 4 -PROD816-1 batch1
2 4 -PROD816-2 batch2
1 5 GTS-03-PROD121-1 batch1
2 5 GTS-03-PROD121-2
3 5 GTS-03-PROD121-3 batch3
4 5 GTS-03-PROD121-4
Use alias and join for record in multiple table.
For i.e. `SELECT table2.id,
table1.pid,
table1.color,
table2.pname,
table2.image
FROM tbl_productcolor table1
JOIN tbl_product table2 ON table1.pid = table2.id;`
Apply your table in this way you can get all the data.