Display only first of duplicate column values - php

How to query for erase the view below?
+-------------------+------------+
| Order_id | Weight |
| 20 | 4 |
| 21 | 5 |
| 22 | 2 |
| 22 | 2 |
+-------------------+------------+
To be like this:
+-------------------+------------+
| Order_id | Weight |
| 20 | 4 |
| 21 | 5 |
| 22 | 2 |
| 22 | |
+-------------------+------------+
When displaying results but not entered into the database.

A simple way is:
select DISTINCT order_id, weight from xyz
UNION
select order_id, null from xyz
group by order_id, weight
having count(*) > 1
Order by weight desc;
The 1st select statement will display all the unique values and 2nd one will retrieve only the repeated values.
In your required output table, it seems like you want to display all the non-repeated rows and the 1st column value of repeated rows but not 2nd column value. The above query will allow you to do that.

OK, here is how to do it:
SELECT
Order_id,
Weight,
if(#order_id = Order_id, '', Weight) as no_dup_weight,
#order_id := Order_id as dummy
FROM Table1
ORDER BY Order_id asc;
You basically need to check to see if the previous Order_id is the same as the current, and if they are, output an empty field.
Here is an SQLFiddle demonstrating the solution.

Do you actually need 2 rows for the dupes? Can't you just use the DISTINCT clause as per http://www.mysqltutorial.org/mysql-distinct.aspx
Or is it important to know what has duplicates. In which case you should look into the GROUP BY clause

Related

Single Query to fetch records from multiple tables with different columns

I have 2 different tables as want to get records in a single query. Currently, I am using 2 queries then merging the array result and then displaying the record. Following is my current code:
$db = JFactory::getDbo();
$query1 = "SELECT a.id as cId, a.title, a.parent_id,a.level FROM `categories` AS a WHERE ( a.title LIKE '%keyword%' )";
$result1 = $db->setQuery($query1)->loadObjectlist(); //gives selected records
$query2 = "SELECT b.id as indId, b.indicator , b.cat_id, b.subcat_id, b.section_id FROM `indicator` as b WHERE ( b.indicator LIKE '%keyword%' )";
$result2 = $db->setQuery($query2)->loadObjectlist(); //gives selected records
$_items = array_merge($result1,$result2); //then using $_items in php code to display the data
It is in Joomla however I just want to know how we can merge these 2 queries into one. I tried the following but it gives the result of first query from categories table.
(SELECT id as cId, title, parent_id,level, NULL FROM `categories` WHERE ( title LIKE '%birth%' ))
UNION ALL
(SELECT id as indId, indicator , cat_id, subcat_id, section_id FROM `indicator` WHERE ( indicator LIKE '%birth%' ))
Desired output:
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| cId | title | parent_id | level | indId | indicator | cat_id | subcat_id | section_id
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| 2874 | births | 2703 | 2 | null | null | null | null | null |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| 13 | birth weight| 12 | 3 | null | null | null | null | null |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| null | null | null | null | 135 | resident births| 23 | 25 | 1 |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| null | null | null | null | 189 | births summary | 23 | 25 | 1 |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
This above output will help to get proper pagination records. I tried to use join but JOIN needs a common column in ON clause. Here, I want all the columns and their values. Basically I want to combine the 2 table records in one query. Any help would be appreciated
Here is an example,
There are a number of ways to do this, depending on what you really want. With no common columns, you need to decide whether you want to introduce a common column or get the product.
Let's say you have the two tables:
parts: custs:
+----+----------+ +-----+------+
| id | desc | | id | name |
+----+----------+ +-----+------+
| 1 | Sprocket | | 100 | Bob |
| 2 | Flange | | 101 | Paul |
+----+----------+ +-----+------+
Forget the actual columns since you'd most likely have a customer/order/part relationship in this case; I've just used those columns to illustrate the ways to do it.
A cartesian product will match every row in the first table with every row in the second:
> select * from parts, custs;
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
1 Sprocket 102 Paul
2 Flange 101 Bob
2 Flange 102 Paul
That's probably not what you want since 1000 parts and 100 customers would result in 100,000 rows with lots of duplicated information.
Alternatively, you can use a union to just output the data, though not side-by-side (you'll need to make sure column types are compatible between the two selects, either by making the table columns compatible or coercing them in the select):
> select id as pid, desc, '' as cid, '' as name from parts
union
select '' as pid, '' as desc, id as cid, name from custs;
pid desc cid name
--- ---- --- ----
101 Bob
102 Paul
1 Sprocket
2 Flange
In some databases, you can use a rowid/rownum column or pseudo-column to match records side-by-side, such as:
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
2 Flange 101 Bob
The code would be something like:
select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
It's still like a cartesian product but the where clause limits how the rows are combined to form the results (so not a cartesian product at all, really).
I haven't tested that SQL for this since it's one of the limitations of my DBMS of choice, and rightly so, I don't believe it's ever needed in a properly thought-out schema. Since SQL doesn't guarantee the order in which it produces data, the matching can change every time you do the query unless you have a specific relationship or order by clause.
I think the ideal thing to do would be to add a column to both tables specifying what the relationship is. If there's no real relationship, then you probably have no business in trying to put them side-by-side with SQL.
As #Sinto suggested the answer for union and dummy column names following is the whole correct query:
(SELECT id as cId, title, parent_id,level, NULL as indId, NULL as indicator , NULL as cat_id, NULL as subcat_id, NULL as section_id FROM `jm_categories` WHERE ( title LIKE '%births%' )) UNION ALL (SELECT NULL as cId, NULL as title, NULL as parent_id,NULL as level, id as indId, indicator , cat_id, subcat_id, section_id FROM `jm_indicator_setup` WHERE ( indicator LIKE '%births%' ))
We have to match the column names from both tables so that we get records as a combination.

Mysql - select and order by two price columns as one

I am facing one problem with selecting data from mysql and I cant figure it out. Try to do research but without luck.
I have table with 4 columns:
id | name | price | discount_price
1 | Test 1 | 150 | 50
4 | test 2 | 130 | 300
2 | test 3 | 200 | 0
3 | test 4 | 130 | 10
4 | test 5 | 80 | 0
And I need to select data and order them by price and if discount_price is not "ZERO", than order by price_discount. Issue is, that now it is not working as I expected. It shows results as first column is sorted and in the end is second column sorted. Depends if I choose ASC or DESC.
I need to achieve something like merge this two columns into one and than sort. Like this:
id | name | price | discount_price
3 | test 4 | 130 | 10*
4 | test 5 | 80* | 0
1 | Test 1 | 150 | 50*
2 | test 3 | 200* | 0
4 | test 2 | 130 | 300*
Is it possible in mysql? Or should sort this afterwards in php ? Thank you for helping.
Try this (the field definitions in the table creation are pseudocode):
CREATE TEMPORARY TABLE sort (id INT, name VARCHAR, INT price, INT discount_price, INT actual_price) ;
INSERT INTO sort (id, name, price, discount_price)
SELECT id, name, price, discount_price
FROM original_table ;
UPDATE sort SET actual_price = price WHERE discount_price = 0 ;
UPDATE sort SET actual_price = discount_price WHERE discount_price != 0 ;
SELECT id, name, price, discount_price FROM sort ORDER BY actual_price ;

MySQL Select second count of pre selected results

Hello I am trying to make a Select where the uses chooses department and would like to have clause WHERE this department is first, let's say we select 10 results from department: Taxes and then make a SUM SELECT of fee WHERE status = 1. Which results be selected based on the first select All the results are coming from the same table.
| id | department | status | fee |
----------------------------------
| 1 | tax | 1 | 20 |
| 2 | tax | 2 | 20 |
| 3 | tax | 1 | 20 |
| 4 | accounting | 1 | 20 |
So I would like to select if department is choose as tax, and status is 1 the sum of FEE columns which should be 40
So far my Select query looks like this:
SELECT P.id, P.fee, (SELECT SUM(P.fee) FROM cases P WHERE status = 1) as fee_USD
FROM cases P WHERE 1";
if (!empty($department)) { $sql .= " AND P.department = '$department'"; }
the last line is checking if department is given as select option. there are other options as well but to make it simple I have pasted only this part of it. Any help is welcome.
In the Current Selection Fee is = 80
You have to add correlation to your query:
SELECT P1.id, P1.fee,
(SELECT SUM(P2.fee)
FROM cases P2
WHERE P2.department = P1.department AND status = 1) as fee_USD
FROM cases P1
WHERE 1 ...
This way the subquery will return the SUM of only those records which are related to the current record of the main query.

MySQL with selecting distinct row

Hello there, I have a schema like this, table name feeds
Where msg_id is unique and its the primary key of the table
| msg_id |commented|
| 1 | 10 |
| 2 | 10 |
| 3 | 10 |
| 4 | 21 |
I want to build a query that would select the last two rows
The output should go like this
| msg_id |commented|
| 3 | 10 |
| 4 | 21 |
In short the query should return the rows with msg_id which have a distinct commented value
Group by the column ment to be unique and select the highest id for every group
select max(msg_id) as msg_id, commented
from your_table
group by commented
Try this -
select max(msg_id), commented from your_table group by commented
SELECT * FROM feeds GROUP BY commented

How to get unique result from below entry?

plan_id | elementclass | table_no | ress_id | UserID | Status
1 | elementclass1 | 1 | 0 | 0006100022 | N
1 | elementclass1 | 1 | 2 | 0006100022 | N
1 | elementclass2 | 2 | 0 | 0006100021 | N
1 | elementclass4 | 3 | 0 | 0006100023 | N
in above row I am expecting as this
if row is having same elementclass,table_no but different ress_id in that condition only take that row which is non zero.If with above condition tow rows having 0 it can take any row .if both rows have non zero then also it can take any one.
Now
for rest of others it can take values with 0.We can use group by to plan_id as there may be multiple plans.
Desired result
plan_id | elementclass | table_no | ress_id | UserID | Status
1 | elementclass1 | 1 | 2 | 0006100022 | N
1 | elementclass2 | 2 | 0 | 0006100021 | N
1 | elementclass4 | 3 | 0 | 0006100023 | N
Please help.
thanks
SELECT * FROM TableName a
WHERE a.ress_id = (SELECT MAX(b.ress_id) FROM TableName b WHERE b.table_no = a.table_no)
GROUP BY a.plan_id,a.table_no
This gives you:
1 result per plai_id and table_no
each result has biggest ress_id in it
First get the maximum ress id per element class. Then select the related records. There may be duplicates. Hence group by element class and ress id.
The following statement does not precisely do what you asked for, but maybe it suffices. In case of a tie you won't get one of the records, but one of the records' plan ids, one of the records' table nos, one of the records' user ids and one of the records' statusses. So the user id may be taken from one record and the status from another when elementclass and ress_id are equal.
select plan_id, mytable.elementclass, table_no, mytable.ress_id, userid, status
from mytable
join
(
select elementclass, max(ress_id) as max_ress_id
from mytable
group by elementclass
) agg on agg.elementclass = mytable.elementclass and agg.max_ress_id = mytable.res_id
group by mytable.elementclass, mytable.ress_id;
(It is possible to write a statement to access complete records in case of ties, but this is much more complicated - at least in MySQL.)
Try this:
SELECT T1.*
FROM TableName T1 JOIN
(SELECT elementclass,table_no,MAX(ress_id) as ress_id
FROM TableName
GROUP BY elementclass,table_no
)T2 ON T1.elementclass=T2.elementclass AND T1.table_no=T2.table_no AND T1.ress_id=T2.ress_id
Explanation:
Here, we are creating a temporary table T2 with maximum of ress_id for each elementclass and table_no. Then we join this table with the original table with these 3 fields and select all records from the original table T1.
Result:
PLAN_ID ELEMENTCLASS TABLE_NO RESS_ID USERID STATUS
-------------------------------------------------------------------
1 elementclass1 1 2 0006100022 N
1 elementclass2 2 0 0006100021 N
1 elementclass4 3 0 0006100023 N
See result in SQL Fiddle.

Categories