SQL code to call all the columns from a Tb expect one column which can be called using As? - mysql

My current code is given below. I wanted to call all the columns from the table using * but the idcastncrew column name should display like castncrewid. In the requirement code, it's not working though, I wish there was a solution for my requirement such as the sample Requirement code.
Current code:-
SELECT idcastncrew AS castncrewid,castncrewname,castncrewtype,castncrewrole,imagelink,vendor,mode FROM subscriber;
Requirement :-
SELECT idcastncrew AS castncrewid, * FROM subscriber;

The closest I think you can get is to have the renamed column twice, once with the new name and once with the old name.
While MySQL does not allow * after an aliased column (causing your second code snippet to give an error), it does allow table.* anywhere...
SELECT idcastncrew AS castncrewid, subscriber.*
FROM subscriber;
To re-iterate; you'll still get a idcastncrew column, but you will ALSO get a castncrewid column.
There is no way to say don't include *this* column when using * in MySQL
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c69c537e46ad29e3c0c8c03d3ebd1bf7

You can alias columns when you alias the table, example as follows
MariaDB [DEV]> create table xxx (id int, str varchar(20));
MariaDB [DEV]> insert into xxx values (1, 'hi');
MariaDB [DEV]> insert into xxx values (2, 'Hello');
MariaDB [DEV]> insert into xxx values (3, 'World');
MariaDB [DEV]> insert into xxx values (4, 'Goodbye');
MariaDB [DEV]> select a.id as id1, a.* from xxx a order by 1;
+------+------+---------+
| id1 | id | str |
+------+------+---------+
| 1 | 1 | hi |
| 2 | 2 | Hello |
| 3 | 3 | World |
| 4 | 4 | Goodbye |
+------+------+---------+

Related

mysql On Duplicate value in field, insert new row with new value

I want to add a new record in a table if duplicate value enters in a unique field. I don't want to update the existing one but want to add a new record by modifying the unique field value.
Is this possible in mysql?
EDIT:
Edited after user comment on this post:
You need write table locking on both of those two processes.
A WRITE lock has the following features:
The only session that holds the lock of a table can read and write data from the table.
Other sessions cannot read data from and write data to the table until the WRITE lock is released.
Also look at SQL UNIQUE Constraint
BEFORE EDIT:
Yes it is possible. And it took me awhile to figure it out. I build this on your input and compering values as test1, test2 etc, where test is always the same and has trailing number. As you specified.
It can be done as MySQL TRANSACTION in 4 steps.
Lets say you have table testT where name is unique to insure we have no doubles.
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
And you want to insert a new item with name test1 we set is as:
SET #newName = 'test1';
Then we need to check if it already exists in table:
SELECT #check:=COUNT(*) FROM testT WHERE name = #newName;
We do a count here to get true or false and save it as #check here so we can compare it later. This will result into 1 row as test1 already exists in table.
Next we do another selection to get the highest number of test* and store it as #number, this next query selects all tests and does a SUBSTRING after 4 latter's giving us all numbers after first 4 latter's. (99999999999) numbers actually just to be sure we don't miss any but in our case result is only "3" because that is last record "test3" in table.
SELECT
#number:= SUBSTRING(name,5,99999999999)
FROM testT;
Now we can do an insert:
INSERT INTO testT(name)
VALUES
(
IF(#check = "", #newName , CONCAT(LEFT(#newName,4),RIGHT(#number,1)+1)
)
);
This tries to insert our #newName into table under IF condition, and that is if our #check is empty then he will insert #newName, if not it will take word test out of string and append a highest #number from earlier and add + 1 too it.
So result for #newName = 'test1' is below. If you change this into #newName = 'test3' result wold be same new insert test4.
**Schema (MySQL v5.7)**
SET #newName = 'test1';
---
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test4 |
---
And if you change it in ANY test* that number does not already exists it will insert it normally. In case below: #newName = 'test6'
SET #newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
This way an insert will always be made.
You can play with this here : View on DB Fiddle just by changing SET #newName = 'test6'
I am no expert and it took me couple of hours to figure this way out, as I wanted to know if this was even possible.
And I would appreciate if any other user can suggestion any other way or improve my method.

MS Access Insert where not exists

I have the following table:
+-----------+--------+
| FirstName | Active |
+-----------+--------+
| Rob | TRUE |
| Jason | TRUE |
| Mike | FALSE |
+-----------+--------+
I would like to insert 'John' (with Active=True) only if an entry for John doesn't exist already where Active=True. I try the following:
insert into testTable (FirstName, Active) values ('John',True) where not exists (select 1 from testTable where FirstName='John' and Active=True)
but i get
'Query input must contain at least one table or query'.
Can anybody help with what I am trying to achieve?
You can't combine Values with a WHERE clause. You need to use INSERT INTO ... SELECT instead.
Since you don't want to insert values from a table, you need to use a dummy table. I use MSysObjects for that purpose (that's a system table that always exists and always contains rows):
INSERT INTO testTable (FirstName, Active)
SELECT 'John', True
FROM (SELECT First(ID) From MSysObjects) dummy
WHERE NOT EXISTS (select 1 from testTable where FirstName='John' and Active=True)
In my case the field already exist in the table so I changed it from an INSERT to an UPDATE query and it worked.

Need to insert CSV values in MySQL column to another table

I have a CSV file containing user information:
'Arlington', '1,3,5,7,9'
'StackExchange', '2,3'
And I will need the above information imported like this:
"User" table:
id | name
1 | 'Arlington'
2 | 'StackExchange'
"User groups" table:
id | user_id | group_id
1 | 1 | 1
2 | 1 | 3
3 | 1 | 5
4 | 1 | 7
5 | 1 | 9
6 | 2 | 2
7 | 2 | 3
What's the easiest way to do this? I have imported the data with a temp column holding the CSV values:
id | name | tmp_group_ids
1 | 'Arlington' | '1,3,5,7,9'
2 | 'StackExchange' | '2,3'
I am thinking if I import it this way, I will know exactly what id gets assigned for the user (the id column in the users table is auto_increment), and so I can use that id as user_id for the "user groups" table.
But now how do I get values from tmp_group_ids into the "User groups" table?
Would appreciate any help! Thanks!
the easy way would be a php or perl script.
You can use the MySQL SUBSTRING() function to split the string and insert the different values into the table. You can do this by writing a function or using a stored procedure.
I had recently a similar problem, I used the function SUBSTRING_INDEX(str,delim,count), using "," as delimiter
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index
INSERT INTO tableUserGroup (userid, groupid)
SELECT
t1.id
, substring_index(t1.tmp_group_ids,',',2)
, substring_index(t1.tmp_group_ids,',',3)
FROM table1 t1
First, insert the names into the User table - with id autonumber, this will work:
INSERT INTO User
(name)
SELECT DISTINCT
name
FROM TempTable
Then:
--- Create a "numbers" table:
CREATE TABLE num
( i INT PRIMARY KEY
) ;
--- Populate it with numbers:
INSERT INTO num
(i)
VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
Then, you can use FIND_IN_SET() function which is handy for this situation (splitting comma-separated fields), like this:
INSERT INTO User_Groups
(user_id, group_id)
SELECT
u.id AS user_id
, num.i AS group_id
FROM User AS u
JOIN TempTable AS t
ON t.name = u.name
JOIN num
ON FIND_IN_SET(num.i, t.tmp_group_ids) > 0

Reorder rows in a MySQL table

I have a table:
+--------+-------------------+-----------+
| ID | Name | Order |
+--------+-------------------+-----------+
| 1 | John | 1 |
| 2 | Mike | 3 |
| 3 | Daniel | 4 |
| 4 | Lisa | 2 |
| 5 | Joe | 5 |
+--------+-------------------+-----------+
The order can be changed by admin hence the order column. On the admin side I have a form with a select box Insert After: to entries to the database. What query should I use to order+1 after the inserted column.
I want to do this in a such way that keeps server load to a minimum because this table has 1200 rows at present. Is this the correct way to save an order of the table or is there a better way?
Any help appreciated
EDIT:
Here's what I want to do, thanks to itsmatt:
want to reorder row number 1 to be after row 1100, you plan to leave 2-1100 the same and then modify 1 to be 1101 and increment 1101-1200
You need to do this in two steps:
UPDATE MyTable
SET `Order` = `Order` + 1
WHERE `Order` > (SELECT `Order`
FROM MyTable
WHERE ID = <insert-after-id>);
...which will shift the order number of every row further down the list than the person you're inserting after.
Then:
INSERT INTO MyTable (Name, `Order`)
VALUES (Name, (SELECT `Order` + 1 FROM MyTable WHERE ID = <insert-after-id>));
To insert the new row (assuming ID is auto increment), with an order number of one more than the person you're inserting after.
Just add the new row in any normal way and let a later SELECT use ORDER BY to sort. 1200 rows is infinitesimally small by MySQL standards. You really don't have to (and don't want to) keep the physical table sorted. Instead, use keys and indexes to access the table in a way that will give you what you want.
you can
insert into tablename (name, `order`)
values( 'name', select `order`+1 from tablename where name='name')
you can also you id=id_val in your inner select.
Hopefully this is what you're after, the question isn't altogether clear.

Cross-checking one MySQL table of text content against another table of keywords

Let's say I have two tables:
Table 1 has the columns NOTE_ID (a unique key) and NOTE_BODY (a big text blurb).
Table 2 has the columns KEYWORD_ID (a unique key) and KEYWORD (a keyword).
I want to get a result set that tells me which keywords each NOTE_BODY contains, without nesting a bunch of loops. So ideally I would get a row for each NOTE_BODY-KEYWORD match.
What's the right way to go about this? I'm unsure if a JOIN+LIKE'%%' does the trick, or if I should be using full-text indexing. Any help much appreciated...
A full text indexing solution is the right way to do this, if you plan to have many rows. You could use MySQL's native solution if you are using the MyISAM storage engine, but you could also consider the popular third-party search engines Sphinx and Apache Lucene.
On the other hand, a simple INNER JOIN would have done the trick:
SELECT t1.note_id, t1.note_body, t2.keyword
FROM table_1 t1
JOIN table_2 t2 ON (t1.note_body LIKE CONCAT('%', t2.keyword, '%'));
Test case:
CREATE TABLE table_1 (note_id int, note_body varchar(100));
CREATE TABLE table_2 (keyword_id int, keyword varchar(50));
INSERT INTO table_1 VALUES (1, 'Hello Stack Overflow');
INSERT INTO table_1 VALUES (2, 'Hello World');
INSERT INTO table_1 VALUES (3, 'Hello, my name is Daniel');
INSERT INTO table_1 VALUES (4, 'Goodbye');
INSERT INTO table_2 VALUES (1, 'Hello');
INSERT INTO table_2 VALUES (2, 'name');
Result:
+---------+--------------------------+---------+
| note_id | note_body | keyword |
+---------+--------------------------+---------+
| 1 | Hello Stack Overflow | Hello |
| 2 | Hello World | Hello |
| 3 | Hello, my name is Daniel | Hello |
| 3 | Hello, my name is Daniel | name |
+---------+--------------------------+---------+
4 rows in set (0.00 sec)