I have a simple table with two columns. The first field represents an id, the second one a name (string value). No field is unique. So, e.g., there are many records like:
What I need is a simple SQL statement which shows me the whole table in the following format and inserts the content into a new table.
Any help?
You have to use group by:
insert into tab2 (name,cnt)
select name, count(1) as cnt
from tab
group by name
Here is more informations about aggregate functions.
SQL Fiddle DEMO
Just use COUNT function to count from_id. And if you want to count in group, use GROUP BY clause for that. Like this one.
SELECT `name`, COUNT(from_id) AS `COUNT`
FROM myTable
GROUP BY `name`;
This will return your desired result.
Now you want to insert it into new table then you can do like this:
INSERT INTO newTable (`name`, `count`)
SELECT `name`, COUNT(from_id) AS `COUNT`
FROM myTable
GROUP BY `name`;
Related
What I mean is, I have table with a "list" column. The data that goes into the "list" is related to addresses, so I sometimes get repeated zip codes for one record in that field.
For example, "12345,12345,12345,12456".
I want to know if it's possible to construct a query that would find the records that have an unknown string that duplicates within the field, such that I would get the records like "12345,12345,12345,12456", but not ones like "12345,45678,09876".
I hope that makes sense.
Yes, it is possible. You need to use a numbers table to convert your delimited string into rows, then use group by to find duplicates, e.g.
CREATE TABLE T (ID INT, List VARCHAR(100));
INSERT INTO T (ID, List)
VALUES (1, '12345,12345,12345,12456'), (2, '12345,45678,09876');
SELECT
T.ID,
SUBSTRING_INDEX(SUBSTRING_INDEX(T.list, ',', n.Number), ',', -1) AS ListItem
FROM T
INNER JOIN
( SELECT 1 AS Number UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5
) AS n
ON CHAR_LENGTH(T.list)-CHAR_LENGTH(REPLACE(T.list, ',', ''))>=n.Number-1
GROUP BY T.ID, ListItem
HAVING COUNT(*) > 1;
If you don't have a numbers table you can create one in a derived query as I have above with UNION ALL
Example on DB Fiddle
With that being said, this is almost certainly not the right way to store your data, you should instead use a child table, e.g.
CREATE TABLE ListItems
(
MainTableId INT NOT NULL, --Foreign Key to your current table
ItemName VARCHAR(10) NOT NULL -- Or whatever data type you need
);
Then your query is much more simple:
SELECT T.ID, li.ItemName
FROM T
INNER JOIN ListItems AS li
ON li.MainTableId = T.ID
GROUP BY T.ID, li.ItemName
HAVING COUNT(*) > 1;
If you need to recreate your original format, this is easily done with GROUP_CONCAT():
SELECT T.ID,
GROUP_CONCAT(li.ItemName) AS List
FROM T
INNER JOIN ListItems AS li
ON li.MainTableId = T.ID
GROUP BY T.ID;
Example on DB Fiddle
I am still unclear what your desired result is based on your question however if it is simply to get all rows where there is a duplicate entry in column list you could do the following:
SELECT * FROM TABLE
WHERE COLUMN IN
(SELECT COLUMN FROM TABLE
having count(*) >1)
I have a MySql database round-about 2.5GB,
The table[A] has following columns, |anoid| |query| |date| |item-rank| |url|
I have just created another table[b] having columns only |query| and |date|
I want to insert all the distinct records in query column, with it's respective date, from Table[A] to [B], is there any fast query?
Use INSERT INTO ... SELECT:
INSERT INTO Tableb(query, date)
SELECT query, MAX(Date) AS MAXDate
FROM Tablea
GROUP BY query
This will give you distinct query with the most recent date.
You can use
insert into table[b](query,date)
select query,date from table[a] order by table[a] asc
INSERT INTO tableB
SELECT * FROM tableA
group by query
Note: please remove id from both the tables while applying the above query.
I obtain a series of values that appear only one time in my database using COUNT in mysql that list below:
valueName
---------
value1
value2
value3
value4
I need a script that retrieves all records in a table where valueName are not the values listed in the initial count, and I need this two steps to run in a single script (doesn't matter how many parts it has).
I've got the script to obtain the list above like this:
SELECT field AS new_name FROM table GROUP BY field HAVING COUNT(field) = 1;
And it works.
The problem is that I don't know how to work with the aggregated result of the first step. Maybe using some kind of function. Or loop (I don't think in SQL..).
I've tried different things like attaching a COUNT inside a WHERE clause and others but it doesn't work.
Please help!
Use a join:
select t.*
from table t join
(SELECT field
FROM table
GROUP BY field
HAVING COUNT(field) > 1
) filter
on t.field = filter.field;
If you have a primary key in your table and an index on table(field, pk), the following is probably faster:
select t.*
from table t
where exists (select 1
from table t2
where t2.field = t.field and t2.pk <> t.pk
);
Try this:
SELECT table.* FROM table
JOIN
(SELECT field FROM table GROUP BY field HAVING COUNT(field) > 1) newtable
ON
table.field = newtable.field;
This should work.
All I need to do is to count all records that match this query... that is the only info I need.. is the count of the records... what is the most efficient way to do that?
SELECT id, country, city
FROM sales
WHERE country='Germany'
AND city='Munich'
AND closed<>0
I mean, I assume this is correct but is there a more efficient way to do this? I will be running this counting query often...
SELECT COUNT(*)
FROM sales
WHERE country='Germany'
AND city='Munich'
AND closed<>0
Should I use * or something more specific?
If you need to count the Null value also for your record count then use count(*) or if ignore the Null value to be counted then use count().
DECLARE #AA AS TABLE (ID INT, NAME VARCHAR(10))
INSERT INTO #AA VALUES(1,NULL)
INSERT INTO #AA VALUES(2,'A')
INSERT INTO #AA VALUES(3,'B')
INSERT INTO #AA VALUES(4,'C')
SELECT * FROM #AA
SELECT COUNT(*) FROM #AA
SELECT COUNT(NAME) FROM #AA
As you execute the above query you can find that there will be four records in #AA table but if you use COUNT(*) if will result 4 and if you use COUNT(NAME) it will result 3 this example is for SQL Server, but the mysql will do same.
Please refer the following link.
MySQL: Fastest way to count number of rows
Hope this helps you.
I'm looking to store the results of a query that returns a list of all the unique values in a particular column, and how many times they are repeated:
SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name;
This returns something like:
col_name
recordA
recordB
recordC
recordD
recordE...
total
39
91817
982027
211872
256...
It's working great and exactly what I need. But I need to store the results into another table (eg. countTable) so I don't have to do the query every time, can index it... etc.
Let's say countTable has the exact same structure as the results here. Two columns: name and count of the same types as the original result.
This is going to probably raise some laughs, but currently I feel like this is close:
INSERT INTO countTable (name, count) SELECT col_name, total FROM
(SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name);
But I get an error: ERROR 1248 (42000): Every derived table must have its own alias
I have no idea how to wrap this query right, or if I'm supposed to use another AS somewhere?
Any help greatly appreciated!!
Thanks
You can do a SELECT right after the INSERT statement. As long as what you are selecting matches the values you want to insert (in this case name and count). You can test what will be inserted into your countTable by just running the select statement by itself.
INSERT INTO countTable (name, count)
SELECT col_name, COUNT(*) AS 'total'
FROM dataTable
GROUP BY col_name;
AH! Turns out I was very close in my original query:
INSERT INTO countTable (name, count) SELECT col_name, total FROM
(SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name);
I DID need to add an extra AS at the very end. Every derived table MUST indeed have its own alias :)
INSERT INTO countTable (name, count) SELECT col_name, total FROM
(SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name) AS count;
But it would seem I'm wrapping it unnecessarily as evidenced by spaceman's answer.