Getting wrong data on join table - php

Well let’s supposed that I have the table horarios with data inside
grdid | curso | disciplina | professor
-----------+------------------+-----------------+------------
231 | Engenharia | 6 | 2
120 | Enfermagem | 1 | 5
And on another table called disciplinas I have the following data
departamento | codigocurso | codigo | disciplina
-------------------+-----------------+-----------+------------
100 | 120 | 1 | numero1
100 | 2121 | 2 | numero2
100 | 2121 | 3 | numero3
200 | 231 | 4 | numero4
200 | 231 | 5 | numero5
200 | 231 | 6 | numero6
With the data that I have inside those tables, by making the join table just like on the codes bellow I am supposed to get the numero6 right? But unfortunately I am getting the numero2 and and I tried to insert another data on table horarios but on the join table is displaying numero5.
What am I doing wrong?
for ($i=0; $i< pg_numrows ($res);$i++){
echo '<table style="font-size:12px;" bgcolor=white width=1027px><tr>';
$curso=pg_result ($res, $i , "curso");
$sql2="select horarios.dias, horarios.inicio, horarios.fim, disciplinas.disciplina, professore1.nomehorario, horarios.sala from horarios
left outer join disciplinas on (horarios.professor = disciplinas.codigo)
left outer join professore1 on (horarios.professor = professore1.numero)
where curso='$curso' order by dias;";

Your join condition is wrong. You should use the disciplina column for it:
select horarios.dias, horarios.inicio, horarios.fim, disciplinas.disciplina, professore1.nomehorario, horarios.sala from horarios
left outer join disciplinas on (horarios.disciplina = disciplinas.codigo)
-- Here ---------------------------------^
left outer join professore1 on (horarios.professor = professore1.numero)
where curso='$curso' order by dias

Related

MySQL SUM of multiple rows from multiple table

I am trying to get the sum of multiple rows from 2 different tables, but somehow the result returns multiple rows.
I need to get the SUM of quotation_item_amount (group by quotation_id) and invoice_item_amount (group by invoice_id) and if I query unpaid quotation, I need to get WHERE SUM(invoice) < SUM(quotation)
So here's my sample table
table client_project_id
+-------------------+-----------+----------------------+
| client_project_id | client_id | client_project_title |
+-------------------+-----------+----------------------+
| 23 | 5 | Project 1 |
| 17 | 9 | Project 2 |
| 54 | 7 | Project 3 |
+-------------------+-----------+----------------------+
table quotation
+--------------+-------------------+------------------+
| quotation_id | client_project_id | quotation_number |
+--------------+-------------------+------------------+
| 1 | 23 | Q/01/2020/001 |
| 2 | 17 | Q/01/2020/002 |
| 3 | 54 | Q/01/2020/003 |
+--------------+-------------------+------------------+
table quotation_item
+-------------------+--------------+-----------------------+
| quotation_item_id | quotation_id | quotation_item_amount |
+-------------------+--------------+-----------------------+
| 1 | 1 | 500 |
| 2 | 1 | 700 |
| 3 | 1 | 600 |
| 4 | 2 | 200 |
| 5 | 2 | 150 |
| 6 | 3 | 900 |
+-------------------+--------------+-----------------------+
table invoice
+--------------+-------------------+------------------+
| invoice_id | client_project_id | invoice_number |
+--------------+-------------------+------------------+
| 1 | 23 | I/01/2020/001 |
| 2 | 17 | I/01/2020/002 |
| 3 | 54 | I/01/2020/003 |
+--------------+-------------------+------------------+
table invoice_item
+-------------------+--------------+-----------------------+
| invoice_item_id | invoice_id | invoice_item_amount |
+-------------------+--------------+-----------------------+
| 1 | 1 | 500 |
| 2 | 1 | 700 |
| 3 | 1 | 600 |
| 4 | 2 | 200 |
| 5 | 2 | 150 |
| 6 | 3 | 900 |
+-------------------+--------------+-----------------------+
The result that I need to obtain is:
SUM of quotation_item_amount and SUM of invoice_item_amount PER client_project_id
To query WHERE SUM(invoice) < SUM(quotation)
Here is my latest try at the query
SELECT
SUM(quotation_item.quotation_item_amount) as quot_amt,
SUM(invoice_item.invoice_item_amount) as inv_amt,
data_client_project.client_project_id,
data_client.client_name
FROM data_client_project a
LEFT JOIN quotation b ON a.client_project_id = b.client_project_id
LEFT JOIN data_client d ON a.client_id = d.client_id
LEFT JOIN invoice i ON a.client_project_id = i.client_project_id
JOIN (
SELECT quotation_id,
SUM(c.quotation_item_amount) as quot_amt
FROM quotation_item c
GROUP BY c.quotation_id
) quotitem
ON b.quotation_id = quotitem.quotation_id
JOIN (
SELECT invoice_id,
SUM(e.invoice_item_price) as inv_amt
FROM invoice_item e
GROUP BY e.invoice_id
) invitem
ON i.invoice_id = invitem.invoice_id
However, this results in multiple duplicate rows of the quotation_item_amount and invoice_item_amount.
Have tried using UNION / UNION ALL and several other queries which just do not work.
Thank you for all your suggestions.
It looks like you are trying to aggregate along two different dimensions at the same time. The solution is to pre-aggregate along each dimension:
SELECT *
FROM data_client_project cp LEFT JOIN
(SELECT q.client_project_id,
SUM(qi.quotation_item_amount * qi.quotation_item_qty) as quot_amt
FROM quotation q JOIN
quotation_item qi
ON qi.quotation_id = q.quotation_id
GROUP BY q.client_project_id
) q
USING (client_project_id) LEFT JOIN
(SELECT i.client_project_id,
SUM(invoice_item_price) as inv_amt
FROM invoice i JOIN
invoice_item ii
ON i.invoice_id = ii.invoice_id
GROUP BY i.client_project_id
) i
USING (client_project_id);
Two notes about your style.
First, you are using arbitrary letters for table aliases. This makes the query quite hard to follow and becomes quite awkward if you add new tables, remove tables, or rearrange the names. Use abbreviations for the tables. Much easier to follow.
Second, I don't really recommend SELECT * for such queries. But, you can avoid duplicated column by replacing ON with USING.
I may be missing something, but your table descriptions do not include a example for data_client or data_client_project Given your example, I expect your row expansion is coming from the first 3 joins.
Make sure that the below is giving you the list of data you want first, then try joining in the calculation:
SELECT *
FROM data_client_project a
LEFT JOIN quotation b ON a.client_project_id = b.client_project_id
LEFT JOIN data_client d ON a.client_id = d.client_id
LEFT JOIN invoice i ON a.client_project_id = i.client_project_id;
#you may want to append the above with a limit 100 for testing.
if you have duplicated rows form the main query then add distinct for obatin a only distinct rows
and andd the where conditio for filtering the result by quotitem.quot_amt < invitem.inv_amt
SELECT distinct a.*, b.*, d.*, i.*
FROM data_client_project a
LEFT JOIN quotation b ON a.client_project_id = b.client_project_id
LEFT JOIN data_client d ON a.client_id = d.client_id
LEFT JOIN invoice i ON a.client_project_id = i.client_project_id
JOIN (
SELECT quotation_id,
SUM(c.quotation_item_amount * c.quotation_item_qty) as quot_amt
FROM quotation_item c
GROUP BY c.quotation_id
) quotitem ON b.quotation_id = quotitem.quotation_id
JOIN (
SELECT invoice_id,
SUM(e.invoice_item_price) as inv_amt
FROM invoice_item e
GROUP BY e.invoice_id
) invitem ON i.invoice_id = invitem.invoice_id
WHERE quotitem.quot_amt < invitem.inv_amt

MySQL: Joining a table to itself, eliminating duplicate rows

I have a query that connects a table to itself. The results contain duplicate rows (sort of). The objective of this query is to produce a list of products most frequently purchased together. Consider this query:
SELECT o1.ITEM
,o2.ITEM as ITEM2
,o3.ITEM AS ITEM3
,count(DISTINCT o1.ORDERNUM) as oCount
FROM orders o1
INNER JOIN orders o2 ON o2.ORDERNUM = o1.ORDERNUM AND o2.ITEM != o1.ITEM
LEFT OUTER JOIN orders o3 ON o3.ORDERNUM = o1.ORDERNUM AND o3.ITEM != o2.ITEM AND o3.ITEM != o1.ITEM
GROUP BY o1.ITEM, o2.ITEM, o3.ITEM
ORDER BY oCount DESC
And the first 12 results:
+-------------+-------------+-------------+--------+
| ITEM | ITEM2 | ITEM3 | oCount |
+-------------+-------------+-------------+--------+
| 02B13.04.GP | 77A04.10 | 45A04.04.GP | 54 |
| 02B13.04.GP | 45A04.04.GP | 77A04.10 | 54 |
| 77A04.10 | 45A04.04.GP | 02B13.04.GP | 54 |
| 45A04.04.GP | 02B13.04.GP | 77A04.10 | 54 |
| 77A04.10 | 02B13.04.GP | 45A04.04.GP | 54 |
| 45A04.04.GP | 77A04.10 | 02B13.04.GP | 54 |
| 57B01.01.GP | 57B01.11.GP | 57B01.10.GP | 12 |
| 57B01.10.GP | 57B01.11.GP | 57B01.01.GP | 12 |
| 57B01.01.GP | 57B01.10.GP | 57B01.11.GP | 12 |
| 57B01.10.GP | 57B01.01.GP | 57B01.11.GP | 12 |
| 57B01.11.GP | 57B01.10.GP | 57B01.01.GP | 12 |
| 57B01.11.GP | 57B01.01.GP | 57B01.10.GP | 12 |
Note that the first 6 results are the same connections, in a different order. The second 6 results have the same issue (and this continues throughout the results). My goal is to have a single record for each item group, not a single row for each combination of each item group.
How can I avoid these repeated results?
Also any advice on a more efficient approach to this query would be welcome (I'd like to add an additional join, but with 1,000,000 orders the resource requirements are getting out of hand).
================================================
EDIT: To answer Darshan's questions
Can you share the table structure:
The table contains the lines for all the orders. If an order contains multiple products, there will be a line for each product (multiple lines for a given order). The only columns of concern in this query are:
ORDERNUM CHAR : Order Number
ITEM CHAR : SKU for the item
QTY INT : Quantity purchased
ORDDATE DATETIME : Order Date
Results returned: All I need is what I listed in the result sample above. The objective is to get a list of the products that are purchased together the most often.
What you want to do is to eliminate duplicated rows regardless of the position; one trick, since you always have all the combinations of items is to filter the results according to a predicate that says item1 < item2 < item3
Here is a possible solution:
SELECT a.item, b.item, c.item, count(*)
from `orders` a left join orders b
on a.ordernum = b.ordernum and a.item <> b.item
left join orders c on a.ordernum = c.ordernum
and a.item <> c.item and b.item <> c.item
where a.item < b.item and b.item < c.item
group by a.item, b.item, c.item
order by count(*) desc

Solving count query issue

I have the following code where i need to select all items from personabisna table and count items with the same personalbisnaId from another table where the both tables share the personalbisnaid
$query="select c.BusinessLogo,
c.PersonalBisnaId,
c.account_id,
AS Ads from personalbisna As c INNER JOIN myads AS b on b.PersonalBisnaId=c.PersonalBisnaId GROUP BY c.PersonalBisnaId LIMIT $itemfrom,$dataperpage";
These are the tables
Personalbisna table
| PersonalBisnaId| account_id| BusinessLogo
---------------------------------------------
| 1 | 23 | qwertyu.jpg
| 2 | 4 | asdfghjk.jpg
| 3 | 12 | 34567gfd.jpg
| 4 | 34 | drtyujhv.jpg
myads table
| MyAdsId | PersonalBisnaId| AdType
---------------------------------------------
| 1 | 2 | logo
| 2 | 2 | business card
| 3 | 3 | logo
| 4 | 2 | caricalture
I have used some already answered questions to solve my problem and i'm really getting totally confused to solve my issue
The above query should output the following
| PersonalBisnaId| account_id| BusinessLogo | AdsCount
-------------------------------------------------------
| 1 | 23 | qwertyu.jpg | 0
| 2 | 4 | asdfghjk.jpg | 3
| 3 | 12 | 34567gfd.jpg | 1
| 4 | 34 | drtyujhv.jpg | 0
This what i have
$query="SELECT
c.BusinessLogo,
c.PersonalBisnaId,
c.account_id,
c.BusinessName,
c.BusinessCategory,
c.BusinessSubCategory,
c.town,
c.estate,
c.street,
c.road,
c.building,
c.Address,
c.city,
c.PhoneNumber,
c.AltPhoneNumber,
c.website,
c.Email,
c.BusinessType
COUNT(MyAdsId) AS AdsCount
FROM personalbisna AS c
LEFT OUTER JOIN myads AS b
ON b.PersonalBisnaId= c.PersonalBisnaId
GROUP BY c.PersonalBisnaId LIMIT $itemfrom,$dataperpage";
Count aggregate is missing in your query.
Also if you want select all items from Personabisna table then instead of INNER JOIN you need to Left/Right Outer Join
SELECT c.personalbisnaid,
c.account_id,
c.BusinessLogo,
Count(AdType) AS AdsCount
FROM personalbisna AS c
LEFT OUTER JOIN myads AS b
ON b.personalbisnaid=c.personalbisnaid
GROUP BY c.personalbisnaid,
c.account_id,
c.BusinessLogo

How to Implement Join In Mysql to Fetch the Following Record

I am new to mysql I have three tables as follows
Table No 1 purchase
+--------+-----------+--------+
| UserID | productID | traID |
+--------+-----------+--------+
| 525 | 2 | 602 |
+--------+-----------+--------+
| 525 | 1001 | 602 |
+--------+-----------+--------+
| 525 | 1002 | 602 |
+--------+-----------+--------+
| 525 | 1 | 602 |
+--------+-----------+--------+
Table No 2 Deals
+--------+-----------+
| dealsid| deals_name|
+--------+-----------+
| 1 | First Deal|
+--------+-----------+
| 2 |Second Deal|
+--------+-----------+
Table No 3 Productmaster
+-----------+--------------+
| productID | product_name |
+-----------+--------------+
| 1001 | HTML |
+-----------+--------------+
| 1002 | JAVA |
+-----------+--------------+
I want the output of the above table as follows
(First Deal , Second Deal , HTML, JAVA)
The where Clause can be implemented to purchase.traID = 602 as I have posted on the above table.
Please help me with some mysql query.
Try this,
SELECT pm.product_name , d.deals_name
FROM purchase p,
deals d,
productmaster pm
WHERE p.productid = d.dealsid
OR p.productid = pm.productid
AND p.traID = 602;
you can use SELECT distinct instead of select
I will suggest to use Stored procedure:
Find result from either table and get union of it as output
CREATE PROCEDURE sp_get_product_name
(
arg_traid int
)
BEGIN
Select pm.product_name
from productmaster pm
inner join purchase p
on pm.productID = p.productID
where p.traID = arg_traid
Union
Select d.deals_name
from deals d
inner join purchase p
on d.dealsID = p.productID
where p.traID = arg_traid
END
Try this:
SELECT *
FROM purchase p,
deals d,
productmaster pm
WHERE p.productid = d.dealsid
OR p.productid = pm.productid AND p.traID = 602;

Data from three tables duplicates when a JOIN statement is used

when I retrieve data from my tables using JOIN, the rows duplicates. The tables are three in number.
Students
--------
StuID | Name |
1 | Appiah John |
2 | Minister A |
Levels
------
| LevelID | Level | Year | StuID |
| 08 | 100 | 2010 | 2 |
| 83 | 200 | 2011 | 1 |
| 45 | 200 | 2011 | 2 |
Ranks
-----
| RankID | Rank | StuID |
| 101 | 1st | 1 |
| 404 | 4th | 2 |
This is my query statement to select some data from the three tables
SELECT
m.StuID,
n.Level,
n.Year,
o.Rank
FROM
Students m
INNER JOIN
Levels n
ON
m.StuID=n.StuID
INNER JOIN
Ranks o
ON
m.StuID=o.StuID
WHERE
m.StuID=2;
OUTPUT
The query above produces a duplicate answer
| StuID | Level | Year |Rank |
| 2 | 100 | 2010 | 4th |
| 2 | 200 | 2011 | null |
| 2 | 100 | 2010 | 4th |
| 2 | 200 | 2011 | null |
DESIRED OUTPUT
I therefore wish that the output would be like below
| StuID | Level | Year |Rank |
| 2 | 100 | 2010 | 4th |
| 2 | 200 | 2011 | null |
QUESTIONS
Where am I going wrong?
Is join the best way to select data from three tables like this?
How can I make a query to get the desired output?
Believe it or not I think the comma between Students m and INNER JOIN is doing it. You're selecting from two separate tuples now, joined on any clause rather than joining the first table to the second to the third.
Try doing a left join instead of an inner join:
SELECT m.StuID,
n.Level,
n.Year,
o.Rank
FROM Students m
LEFT JOIN Levels n ON (m.StuID = n.StuID)
LEFT JOIN Ranks o ON (m.StuID = o.StuID)
WHERE m.StuID = 2
How about using select distinct m.StuID?
You can try something like this
SELECT distinct m.StuID, n.Level, n.Year, o.Rank
FROM Students m INNER JOIN Levels n ON m.StuID=n.StuID
INNER JOIN Ranks o
ON m.StuID=o.StuID WHERE m.StuID=2;

Categories