how to pull data from two tables SQL based on date - mysql

I have two tables... cloads and jpurch I need to pull transactionamount and transaction date column from both tables using one query. The transactions I need to pull must be between a date range of 1-1-2016 and 3-1-2016. Obviously the query I posted below wont work since it doesn't even address the jpurch in the where statement. The transaction dates do not need to match. I need all data for those columns.
select c.transactiondate, c.transactionamount, d.transactiondate, d.transactionamount
from cloads c, jpurch d
where c.transactiondate between '2016-05-01' and '2016-06-06'

#sanky send a good article on joins and is a good place to start. #SujeetSinha also brings up a point about how you will relate one table to the other.
I suspect the answer is you want only records between the tables that match (INNER JOIN) and that you want to match on transactiondate from one table to the other. In that case you could write a query like below. Because both tables have to match on an inner join your where statement for cloads would also filter jpurch.
select
c.transactiondate
,c.transactionamount
,d.transactiondate
,d.transactionamount
from
cloads c
INNER JOIN jpurch d
ON c.transactiondate = d.transactiondate
where
c.transactiondate between '2016-05-01' and '2016-06-06'
Thanks for More Info seems we as a community are still awaiting some help on what you want the data to look like in order to best guide you in your query. If you can take 3-4 rows from each of your tables show us the beginning data and a mock up of how you want it to look from those rows we will better be able to assist you.
If no relation and into 1 table are up meaning you want to APPEND one table to the other? If so use a UNION or UNION ALL depending on if you want all of the data returned or only DISTINCT values of it. ALL means give you everything with UNION alone means don't repeat rows that are already in the table on top of the union statement.
select
c.transactiondate
,c.transactionamount
from
cloads c
where
c.transactiondate between '2016-05-01' and '2016-06-06'
UNION ALL
select
d.transactiondate
,d.transactionamount
from
jpurch d
where
d.transactiondate between '2016-05-01' and '2016-06-06'

Related

SQL Temporary Table or Select

I've got a problem with MySQL select statement.
I have a table with different Department and statuses, there are 4 statuses for every department, but for each month there are not always every single status but I would like to show it in the analytics graph that there is '0'.
I have a problem with select statement that it shows only existing statuses ( of course :D ).
Is it possible to create temporary table with all of the Departments , Statuses and amount of statuses as 0, then update it by values from other select?
Select statement and screen how it looks in perfect situation, and how it looks in bad situation :
SELECT utd.Departament,uts.statusDef as statusoforder,Count(uts.statusDef) as Ilosc_Statusow
FROM ur_tasks_details utd
INNER JOIN ur_tasks_status uts on utd.StatusOfOrder = uts.statusNR
WHERE month = 'Sierpien'
GROUP BY uts.statusDef,utd.Departament
Perfect scenario, now bad scenario :
I've tried with "union" statements but i don't know if there is a possibility to take only "the highest value" for every department.
example :
I've also heard about
With CTE tables, but I don't really get how to use it. Would love to get some tips on it!
Thanks for your help.
Use a cross join to generate the rows you want. Then use a left join and aggregation to bring in the data:
select d.Departament, uts.statusDef as statusoforder,
Count(uts.statusDef) as Ilosc_Statusow
from (select distinct utd.Departament
from ur_tasks_details utd
) d cross join
ur_tasks_status uts left join
ur_tasks_details utd
on utd.Departament = d.Departament and
utd.StatusOfOrder = uts.statusNR and
utd.month = 'Sierpien'
group by uts.statusDef, d.Departament;
The first subquery should be your source of all the departments.
I also suspect that month is in the details table, so that should be part of the on clause.

SQL query giving repetitive results

I have two tables and I want to fetch select columns from the tables.
table 1 is sfpinventoryinfo and table 2 is opticalportinfo.
Both have NEID as common.
SELECT
sfpinventoryinfo.NEID,
sfpinventoryinfo.SlotNumber,
sfpinventoryinfo.PortNo,
sfpinventoryinfo.PortType,
sfpinventoryinfo.`Type`,
sfpinventoryinfo.SN,
sfpinventoryinfo.GenDes,
sfpinventoryinfo.ApplicationCode,
opticalportinfo.ChannelFrequency
FROM
sfpinventoryinfo
JOIN
opticalportinfo ON sfpinventoryinfo.NEID = opticalportinfo.NEID;
But I am getting weird results:
As shows above result, Slot no 4 should have only 1 entry for port instead of 5
It's likely your opticalportinfo has six rows with the value 13 in NEID. So, your join produces all six rows in your result set.
It's hard to guess the "right" way to choose which of those six rows to use without knowing more about your application. You can hack around the problem with SELECT DISTINCT if you must. But it's a hack.
You clearly have duplicates in one or both tables. In your example data, the entire row looks duplicated, so you could use select distinct so entire rows are not repeated:
SELECT DISTINCT i.NEID, i.SlotNumber, i.PortNo, i.PortType, i.`Type`, i.SN,
i.GenDes, i.ApplicationCode, oi.ChannelFrequency
FROM sfpinventoryinfo i JOIN
opticalportinfo op
ON i.NEID = oi.NEID;
Or perhaps GROUP BY:
SELECT i.NEID, i.SlotNumber, i.PortNo, i.PortType, i.`Type`, i.SN,
i.GenDes, i.ApplicationCode, MAX(oi.ChannelFrequency)
FROM sfpinventoryinfo i JOIN
opticalportinfo op
ON i.NEID = oi.NEID
GROUP BY i.NEID, i.SlotNumber, i.PortNo, i.PortType, i.`Type`, i.SN,
i.GenDes, i.ApplicationCode;
That said, you really need to understand why there are duplicates and adjust your query or fix your data.

MySQL INNER JOIN with GROUP BY and COUNT(*)

I've never been able to get my head around INNER JOINs (or any other JOIN types for that matter) so I'm struggling to work out how to use it in my specific situation. In fact, I'm not even sure if it's what I need. I've looked at other examples and read tutorials but my brain just doesn't seem to work the way needed to truly get it (or it doesn't function at all).
Here's the scenario:
I have two tables -
phone_numbers - this table has a list of phone numbers that
belong to lots of different customers. A single customer can have
multiple numbers. For simplicity's sake, we'll say the fields are
'number_id', 'customer_id', 'phone_number'.
call_history - this table has a record of every single call that one of these
numbers in the first table could have had. There's a record for
every individual call going back years. Again, for simplicity,
we'll say the relevant fields are customer_id, phone_number,
call_start_time.
What I'm trying to accomplish is to find all of the numbers that belong to a particular customer_id in the phone numbers table and use that information to search through the call_history table and find the number of calls each phone number has received, and group that by the number of calls for each number, preferably also showing zeros where a number hasn't received any calls at all.
The reason the zero calls is important is because that's the data I'm interested in. Otherwise, I could just get all the information out of the call_history table. But what I'm trying to achieve is find the numbers with no activity.
All I've been able to accomplish is run one query to get all of the numbers belonging to one customer:
SELECT customer_id, phone_number FROM phone_numbers WHERE customer_id = Y;
Then run a second query to get all phone calls for that customer_id for a set duration:
SELECT customer_id, phone_number, COUNT(*) FROM call_history WHERE customer_id = Y and call_start_time >= DATE_SUB(SYSDATE(), INTERVAL 30 DAY) GROUP BY phone_number;
I've then had to use the data returned from both queries and use a VLOOKUP function in Excel to match number of calls for each individual number from the second query to the list of all numbers from the first query, thus leaving blanks in my "all numbers" table and identifying those numbers that had no calls for that time period.
I'm hoping there's some way to do all of this with a single query and return a table of results, listing the zero number of calls with it and eliminate the whole manual Excel bit as it's not overly efficient and prone to human error.
Without at least a workable example from you, it's not easy to re-create your situation. Anyway, INNER JOIN might not return the result as how you expected. In my short time with MySQL, I mainly use 2 types of JOIN; one is already mentioned and the other is LEFT JOIN. From what I can understand in your question, what you want to achieve can be done by using LEFT JOIN instead of INNER JOIN. I may not be the best person to explain this to you but this is how I understand it:
INNER JOIN - only return anything that match in ON clause between two (or more) tables.
LEFT JOIN - will return everything from the table on the left side of the join and return NULL if ON get no match in the table on the right side of the join .. unless you specify some WHERE condition from something on the right table.
Now, here is my query suggestion and hopefully it'll be useful for you:
SELECT A.customer_id, A.phone_number,
SUM(CASE WHEN call_start_time >= DATE_SUB(SYSDATE(), INTERVAL 30 DAY)
THEN 1 ELSE 0 END) AS Total
FROM phone_numbers A
LEFT JOIN call_history B
ON A.customer_id=B.customer_id
GROUP BY A.customer_id,A.phone_number;
What I did here is I LEFT JOIN phone_numbers table with call_history on customer_id and I re-position the WHERE call_start_time >= .. condition into a CASE expression in the SELECT since putting it at WHERE will turn this into a normal join or inner join instead.
Here is an example fiddle : https://www.db-fiddle.com/f/hriFWqVy5RGbnsdj8i3aVG/1
For Inner join You should have to do like this way..
SELECT customer_id,phone_number FROM phone_numbers as pn,call_history as ch where pn.customer_id = ch.customer_id and call_start_time >= DATE_SUB(SYSDATE(), INTERVAL 30 DAY) GROUP BY phone_number;
Just add table name whatever you want to join and add condition

I need to retrieve individual column from 3 different tables

My Sql Server database has three tables (Amount, wthdrwl, spent), each table has got id, and amount column.
I want to retrieve the amount column from these three different tables.
For both MySQL, SQL-Server, use UNION (implicit distinct) or UNION ALL:
SELECT Amount FROM Amount
UNION ALL
SELECT Amount FROM wthdrwl
UNION ALL
SELECT Amount FROM spent
I suppose there is some relation between three tables
SELECT A.Amount AS Amount ,
W.Amount AS Withdrawal ,
S.Amount AS Spent
FROM Amount A
LEFT OUTER JOIN wthdrwl W ON A.ID = W.ID
LEFT JOIN spent S ON A.ID = S.ID
Check here- SqlFiddle
Given your comment above, use a fixed string to indicate which table the values came from:
SELECT 'Amount' AS source, Amount FROM Amount
UNION ALL
SELECT 'whtdrwl' AS source, Amount FROM whtdrwl
UNION ALL
SELECT 'spent' AS source, Amount FROM spent
then you can easily identify the rows. You could write a query that does this as a single row with 3 columns, but it's far easier doing it this way.
If you want to put them all on one line then you have to have a way to link the columns together via a 2nd column, for example a txnId column that occurs in each of the 3 tables. Then you could do something like:
SELECT Amount.Amount Amt, whtdrwl.Amount Wdrl, spent.Amount Spd
FROM Amount, whthdrwl, spent
WHERE Amount.txnId=wthdrwl.txnId
Amount.txnId=spent.txnId
Use the following query-
select amount.amount, wthdrwl.amount, spent.amount from amount, wthdrwl, spent where amount.amount=wthdrwl.amount and wthdrwl.amount=spent.amount;
Here you have to use the table name along with the attribute to distinctly identify the amount attribute from 3 different table. You need to check for the equality of the id attribute in all 3 tables to correspond to a particular entity in a row of the resultset.

Join TableA, TableB and TableC to get data from TableA and TableC

Why I am getting so many records for this
SELECT e.OneColumn, fb.OtherColumn
FROM dbo.TABLEA FB
INNER JOIN dbo.TABLEB eo ON Fb.Primary = eo.foregin
INNER JOIN dbo.TABLEC e ON eo.Primary =e.Foreign
WHERE FB.SomeOtherColumn = 0
When I am running this I am getting Millions of records which is not the correct case, all tables has less number of records.
I need to get the columns from TableA and TableC and because they are not joined logically so I have to use TableB to act as bridge
EDIT
Below is the count:
TABLEA = 273551
TABLEB = 384412
TABKEC = 13046
Above Query = After 2 minutes I have forcefully canceled the query.. till that time the count was 11437613
Any suggestion?
To figure out what is going on in such a query where the results are not as expected, I tend to do this. First I change to a SELECT * (Note this is only for figuring out the problem, do not use SELECT * on production, ever!) Then I add an order by for the ID frield from tableA if there is not one in the query.
So now I run the query up to the first table including any where conditions that are from the first table. I comment out the rest. I note the number of records returned.
Now I add in the second table and any where conditions from it. If I am expecting a one to relationship, and if this query doesn't return the smae number of records, then I look at the data that is being returned to see if I can figure out why. Since the contents are ordered by the table1 ID, you can ususally see examples of some records that are duplicated fairly easily and then scroll over until you find the field that causes the differnce. Often this means that you need some sort of addtional where clause or aggregation on the fields in the next table to limit to only one record. JUSt note down the problem at this point though as you may be able tomake the change more effectively in the next join.
So add inteh the third table and again, not the number of records and then look closely at the data where the id from A is repeated. LOok at the columns you intend to return, are they always teh same for an id? If they are differnt then you do not havea one-one relationship and you need to understand that either theri is a data integrity problem or you are mistaken in thinking there is a one-to-one. If tehy are the same, then a derived table may be in order. You only need the ids from tableb so the join could look something like this:
JOIN (SELECT MIn(Primary), foreign FROM TABLEB GROUP BY foreign) EO ON Fb.Primary = eo.foreign
Hope this helps.