find mySQL duplicates and edit their specific fields - mysql

I have a table where the important fields are CompanyName and CompanyID. Right now there are a lot of rows with identical CompanyNames, but their CompanyIDs are unique. What I want to do is find all rows with exact CompanyNames and take one of their CompanyIDs (doesn't matter which) and apply it to all duplicates. I'm using this code to find all duplicates:
SELECT `CompanyName` , COUNT( `CompanyName` ) AS NumOccurrences
FROM `product_tbl`
GROUP BY `CompanyName`
HAVING (
COUNT( `CompanyName` ) >1
)
What do I need to add to accomplish what I want to do?

This should work:
UPDATE `product_tbl` `PA`,
(
SELECT `CompanyName`, `CompanyID`
FROM `product_tbl`
GROUP BY `CompanyName`
) `PB`
SET `PA`.`CompanyID` = `PB`.`CompanyID`
WHERE `PA`.`CompanyName` = `PB`.`CompanyName`;

Related

fetch datas from two tables and differentiate between them

I have two tables and want displays rows from the two one in the same page ordered by date created.
Here my query:
SELECT R.*, R.id as id_return
FROM return R
UNION
ALL
SELECT A.*, A.id as id_buy
FROM buy A
WHERE
R.id_buyer = '$user' AND R.id_buyer = A.id_buyer AND (R.stats='1' OR R.stats='3') OR A.stats='4'
ORDER
BY R.date, A.date DESC LIMIT $from , 20
With this query i get this error message:
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in ...
And here how i think i can differentiate between the results: (Knowing if the result is from the table RETURN or from the table BUY)
if(isset($hist_rows["id_return"])) {
// show RETURN rows
} else {
// show BUY rows
}
Please what is wrong with the query, and if the method to differentiate between tables are correct ?
EDIT
Here my tables sample:
CREATE TABLE IF NOT EXISTS `return` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_buyer` INT(12) NOT NULL,
`id_seller` INT(12) NOT NULL,
`message` TEXT NOT NULL,
`stats` INT(1) NOT NULL,
`date` varchar(30) NOT NULL,
`update` varchar(30)
PRIMARY KEY (`id`)
)
CREATE TABLE IF NOT EXISTS `buy` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_buyer` INT(12) NOT NULL,
`product` INT(12) NOT NULL,
`title` VARCHAR(250) NOT NULL,
`stats` INT(1) NOT NULL,
`date` varchar(30) NOT NULL
PRIMARY KEY (`id`)
)
Be sure the two table return and buy have the same number (and type sequence) of colummns .. if not the query fails
try select only the column you need from both the table and be sure that these are in correspondenting number and type
SELECT R.col1, R.col2, R.id as id_return
FROM return R
UNION ALL
SELECT A.col1, A.col2, A.id as id_buy
FROM buy A
WHERE
........
Looking to your code you should select the same number and type of column form boith the table eg de sample below:
(where i have added the different column and selecting null from the table where are not present)
I have aslore referred the proper where condition to each table ..
SELECT
R.'from return' as `source_table`
, R.`id`
, R.`id_buyer`
, null as product
, null as title
, R.`id_seller` as id_seller
, R-`message`
, R.`stats`
, R.`date`
, R.`update`
FROM return R
WHERE R.id_buyer = '$user'
AND (R.stats='1' OR R.stats='3')
UNION ALL
SELECT
A.'from buy'
, A.`id`
, A.`id_buyer`
, A.`product`
, A.`title`
, null
, null
, A.`stats`
, A.`date`
, null
FROM buy A
WHERE
A.id_buyer = '$user'
AND A.stats='4'
ORDER BY `source table`, date DESC LIMIT $from , 20
for retrive te value of the first column you should use in your case
echo $hist_rows["source_table"];
Otherwise i the two table are in some way related you should look at a join (left join) for link the two table and select the the repated column
(but this is another question)
But if you need left join you can try
SELECT
R.`id`
, R.`id_buyer`
, R.`id_seller` as id_seller
, R-`message`
, R.`stats`
, R.`date`
, R.`update`
, A.`id`
, A.`id_buyer`
, A.`product`
, A.`title`
, null
, null
, A.`stats`
, A.`date`
FROM return R
LEFT JOIN buy A ON R.id_buyer = A.id_buyer
AND R.id_buyer = '$user'
AND (R.stats='1' OR R.stats='3')
AND A.stats='4'
ORDER BY R.date DESC LIMIT $from , 20
When you use union all, the queries need to have exactly the same columns in the same order. If the types are not quite the same, then they are converted to the same type.
So, you don't want union all. I'm guessing you want a join. Something like this:
SELECT r.co1, r.col2, . . ., r.id as id_return,
b.col1, b.col2, . . ., b.id as id_buy
FROM return r JOIN
buy b
ON r.id_buyer = b.id_buyer
WHERE r.id_buyer = '$user' and
(r.stats in (1, 3) OR A.stats = 4)
ORDER BY R.date, A.date DESC
LIMIT $from, 20;
This query is only a guess as to what you might want.
Since you're using a union, select a string that you set identifying each query:
SELECT 'R', R.*, R.id as id_return
FROM return R
UNION
ALL
SELECT 'A', A.*, A.id as id_buy
This way your string 'R' or 'A' is the first column, showing you where it came from. We can't really know why it's failing without the full query, but I'd guess your $from might be empty?
As for your
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in ...
Run the query directly first to get the sql sorted out before putting it into your PHP script. The boolean false indicates the query failed.

msql query FROM another msl query

I am new to SQL, so I am not too sure how to go about this query that I have to do ...
I have multiple tables which all have 2 columns that i want to take (date_added and path).
So I did an Union select ("date_added" and "path") for each table. So I now have a table with all rows from all the tables I want:
SELECT `date_added`, `path` FROM `art_1` UNION SELECT `date_added`, `path` FROM `art_5484`
This works fine, but now I need to get the row with the lowest date ( I use min function). So I want to do select on the table that I got from my last query so I do:
SELECT `path`
FROM cross_join = (SELECT `date_added`, `path` FROM `art_1` UNION SELECT `date_added`, `path` FROM `art_5484`)
WHERE `date_added` = MIN(`date_added`)
But this doesn't work; I am guessing it's a syntax error, but i can't see where ...
if anybody could help me out, that would be great !
One way to get the minimum date is to use order by and limit:
SELECT `path`
FROM (SELECT `date_added`, `path` FROM `art_1` UNION ALL
SELECT `date_added`, `path` FROM `art_5484`
) a
ORDER BY date_added DESC
LIMIT 1;
Note: this returns only one value, even if when there are duplicates. Also, I changed the UNION to UNION ALL. You should use UNION ALL by default, because UNION incurs the overhead of removing duplicates.

MySQL Select unique sorted field values

I've trying to concatenate the values of 2 GROUP_CONCAT( columns ) from a single table that's been joined twice, then get the unique items from the list.
I can do all this outside of my query but if possible it would be nice to just pull the data from the DB with a JOIN and some fancy string manipulation.
Simply put, I want to produce 1,2,3,4 from selecting 1,2,3 and 1,3,4. The 1,2,3 adn 1,3,4 are the results of the GROUP_CONCAT on the twice joined table. I can get this far:
SELECT CONCAT_WS(
",",
"1,2,3",
"1,3,4"
)
Which outputs 1,2,3,1,3,4
I'd like to be able to do something like:
-- NOTE TO SKIM READERS: THIS QUERY WILL NOT WORK
SELECT
SORT_LIST(
DISTINCT
CONCAT_WS(
",",
"1,2,3",
"1,3,4"
)
)
-- NOTE TO SKIM READERS: THIS QUERY WILL NOT WORK
But I can't find anything like that in MySQL.
The 1,2,3 and 1,3,4 have already been produced with GROUP_CONCAT( DISTINCTcol)
As stated in my comment I worked out a way to achieve distinct concatenated lists of strings using a sub query:
DROP TABLE IF EXISTS `test1234`;
CREATE TABLE `test1234` (
`val` int(1),
`type` varchar(1)
);
INSERT INTO `test1234` VALUES
( 1, 'a' ),
( 2, 'a' ),
( 3, 'a' ),
( 1, 'b' ),
( 3, 'b' ),
( 4, 'b' );
SELECT GROUP_CONCAT( `val` ) AS `vals`
FROM (
(
SELECT `val` FROM `test1234` WHERE `type` = 'a'
) UNION DISTINCT (
SELECT `val` FROM `test1234` WHERE `type` = 'b'
)
) AS `test`;
DROP TABLE IF EXISTS `test1234`;
This selected 1,2,3,4

How to sort search results to display the first user with picture and after the others in MySQL

I have a problem with grouping and sorting.
(
SELECT
`subdomain` AS `id`,`name`,`lastname`,IF(`category` NOT LIKE '',`category`,0) AS `category`,`level`,`image`,`description` AS `summary`, '1' AS `type`
FROM
`user_professionals`
WHERE `keywords`='%{$keywords}%' AND `active`='1' AND `search`='1' AND
NULLIF(CONCAT(`name`, `lastname`), '') IS NOT NULL AND NULLIF(`description`, '') IS NOT NULL AND NULLIF(`category`, '') IS NOT NULL
GROUP BY `image`, `id`
ORDER BY `image` DESC
)
UNION
(
SELECT
`id`,`name`,`lastname`,IF(`category` NOT LIKE '',`category`,0) AS `category`,`level`,`image`,`summary`, '2' AS `type`
FROM
`users_amateurs`
WHERE `keywords`='%{$keywords}%' AND
`on_hold`='0' AND (`level`='2' OR `level`='3') AND `register`='1' AND `banned`='0'
AND
NULLIF(CONCAT(`name`, `lastname`), '') IS NOT NULL AND NULLIF(`summary`, '') IS NOT NULL AND NULLIF(`category`, '') IS NOT NULL
GROUP BY `image`, `id`
ORDER BY `image` DESC
)
LIMIT 100
PROBLEM:
Searching must be in two separate tables at the same time what should give a combined result in one query. Sorting and grouping needs to go in the following order:
Professional Users with images
Professional Users without images
Amateur Users with images
Amateur Users without images
This query works very well but the problem is sorting.
Thanks!

need select from two fields, unique in first based on highest of second

I have a table with three fields, an ID, a Date(string), and an INT. like this.
+---------------------------
+BH|2012-09-01|56789
+BH|2011-09-01|56765
+BH|2010-08-01|67866
+CH|2012-09-01|58789
+CH|2011-09-01|56795
+CH|2010-08-01|67866
+DH|2012-09-01|52789
+DH|2011-09-01|56665
+DH|2010-08-01|67866
I need to essentially for each ID, i need to return only the row with the highest Date string. From this example, my results would need to be.
+---------------------------
+BH|2012-09-01|56789
+CH|2012-09-01|58789
+DH|2012-09-01|52789
SELECT t.id, t.date_column, t.int_column
FROM YourTable t
INNER JOIN (SELECT id, MAX(date_column) AS MaxDate
FROM YourTable
GROUP BY id) q
ON t.id = q.id
AND t.date_column = q.MaxDate
SELECT id, date, int
FROM ( SELECT id, date, int
FROM table_name
ORDER BY date DESC) AS h
GROUP BY id
Replace table_name and columns to the right ones.
Assuming the following structure:
CREATE TABLE `stackoverflow`.`table_10357817` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Date` datetime NOT NULL,
`Number` int(11) NOT NULL,
`Code` char(2) NOT NULL,
PRIMARY KEY (`Id`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
The following query will wield the expected results:
SELECT Code, Date, Number
FROM table_10357817
GROUP BY Code
HAVING Date = MAX(Date)
The GROUP BY forces a single result per Code (you called it id) and the HAVING clauses returns only the data where it matches the max date per code/id.
Update
Used the following data script:
INSERT INTO table_10357817
(Code, Date, Number)
VALUES
('BH', '2012-09-01', 56789),
('BH', '2011-09-01', 56765),
('BH', '2010-08-01', 67866),
('CH', '2012-09-01', 58789),
('CH', '2011-09-01', 56795),
('CH', '2010-08-01', 67866),
('DH', '2012-09-01', 52789),
('DH', '2011-09-01', 56665),
('DH', '2010-08-01', 67866)