I am VERY new to SQL and I am having a little trouble.
Let's say I have a table, called data, with two columns, class, and name.
I want to create the column math if it doesn't exist, and give it a value of John.
I can do this with:
INSERT INTO data VALUES ('math','John')
But if I change John to Steve, I want math to have a value of "John","Steve".
But instead, it creates another row called "math" with a value of "Steve", how can I make this insert into the same column?
Thanks
I would strongly recommend against storing a CSV list of names in your table. CSV is hard to query, update, and maintain. Actually, there is nothing at all wrong with your current approach:
class | name
math | John
math | Steve
Data in this format can easily be queried, because it is relational. And if you need to add, update, or remove a name associated with a class, it becomes a one record affair without having to deal with CSV. Note that if you really need a CSV representation, you can still achieve that using SQLite's GROUP_CONCAT() function:
SELECT class, GROUP_CONCAT(name, ',') AS names
FROM yourTable
GROUP BY class
Not totally sure about SQLite but the normal command usually is something like:
ALTER TABLE table_name
ADD column_name datatype
Then insert into
Related
I need to create a column name based on the value of other columns. I need to return a value from a column, but the specific name depends on the value insert on other table.
From intance:
Table A
Column1 | Column2
1 2
Base on that values I need to go to the table B to the column "VE12".
I need this dynamiclly, so the execute(#query) is my last option and I would like to avoid CASE WHEN statments because I have more than 50 options.
My query will be something like:
select case when fn.tab=8 and fo.pais=3 then cp.ve83 end
FROM fn
INNER JOIN fo ON fo.stamp = fn.stamp
INNER JOIN cp
If the value in the column tab is 8 and the value in column pais is 3 I should return the value in column ve83.
Thanks for all the help!
The only sensible option is to go back to the business meaning of the data and redesign the database according to that, instead of according to "technique-oriented abstractions" such as these that SQL was never intended to support.
The main reason for this is that SQL was founded on FIRST order logic, and this precludes supporting stuff like varying domains. Which you are doing (or at least seeking to do) because ve12 could be a DATETIME and ve83 could be a VARCHAR and ve56 coulb be a BLOB etc. etc. So there is just no way for you [or anyone else] to determine the data type of the results in your query, and it is even more impossible to attach meaning to what comes out of your desired query precisely because of this varying-domain and varying-source characteristic.
In database table in Informix I have columns like this:
Table name is MYTABLE
key 1234
value 'POCO','LOCD',MACD'
Now I want to use this in a query like this
select * from table where symbol in (select value from MYTABLE where key='1234');
But this query is not working as value is stored as char and
output of select value from MYTABLE where key='1234' would be something like
"'POCO','LOCD',MACD'"
Is there a way to make this work. I want to achieve this in a single query.
Please suggest a better approach.
You cannot interpolate values like that. The database optimiser cannot be expected to know that value is going to return a string that looks like a list, which is to be interpreted in a list context.
Since you ask for a better approach…
That design breaks numerous fundamental rules about how databases should be structured. At a minimum, the 'value' column should be a COLLECTION data type, so that its role as a list of values is properly articulated. Personally I would create a standard, relational bridging table:
MYTABLE
key col1 col2
1234 .. ..
MYVALUE
key value
1234 POCO
1234 LOCD
1234 MACD
This is not the easy way out suggested by others, but it is the right answer.
I have 2 sqlite databases, and I'm trying to insert data from one database to another. For example, "db-1.sqlite" has a table '1table' with 2 columns ('name', 'state'). Also, "db-2.sqlite" has a table '2table' with 2 columns ('name', 'url'). Both tables contain a list of 'name' values that are mostly common with each other but randomized, so the id of each row does not match.
I want to insert the values for the 'url' column into the db-1's table, but I want to make sure each url value goes to its corresponding 'name' value.
So far, I have done this:
> sqlite3 db-1.sqlite
sqlite> alter table 1table add column url;
sqlite> attach database 'db-2.sqlite' as db2;
Now, the part I'm not sure about:
sqlite> insert into 1table(url) select db2.2table.url from db2.2table where 1table.name==db2.2table.name
If you look at what I wrote above, you can tell what I'm trying to accomplish, but it is incorrect. If I can get any help on the matter, I'd be very grateful!!
The equality comparison operator in SQL is =, not ==.
Also, I suspect that you should be updating 1table, rather then inserting in it.
Finally, your table names start with digits, so you need to escape them.
This SQL should work better:
update `1table`
set url = (select db2.`2table`.url
from db2.`2table`
where `1table`.name = db2.`2table`.name);
I'm using a postgresql install to house my data.
My Post model has an attribute called "selection" which currently stores data within a TEXT column in the form of: "x1,x2,x3,x4,x5..."
When I need to access this data i split it on the the comma and do my thing with it.
I'm prototyping an app so i quickly just did the easiest thing when i was writing it but now i can see an alternative option would be to create a table for "selections" and associate it back to the post, then have individual rows for each bit.
My question is, how or when do i make the choice to store or not data like this?
Thank you
PostgreSQL has array types - so you can use a "text[]" type
postgres=# create table xxx(a text[]);
CREATE TABLE
postgres=# insert into xxx values(array['x1','x2']);
INSERT 0 1
postgres=# insert into xxx values(array['x1','x2','x3']);
INSERT 0 1
postgres=# select * from xxx where 'x1' = ANY(a);
a
------------
{x1,x2}
{x1,x2,x3}
(2 rows)
postgres=# select * from xxx where 'x3' = ANY(a);
a
------------
{x1,x2,x3}
(1 row)
You can use index for large data too
If those represent other data elements in other tables in your database, then I would never store it as a comma separated string.
SQL in general is optimized for set-based arithmetic and functions, not for string parsing.
The only scenario that I can think of where the string version may be easier/faster is if you want to find a specific set of values and ONLY those values, i.e. Col = 'A1, B2, C3, d4'.
Otherwise, if you want to check individual fields or do other comparisons, storing that data in a normalized table is the best course of action. It's more extensible, easier and more efficient to check for specific values, and will make other operations on that table quicker (since you store less data in-row for that main table).
I have a query in MS Access which creates a table from two subqueries. For two of the columns being created, I'm dividing one column from the first subquery into a column from the second subquery.
The datatype of the first column is a double; the datatype of the second column is decimal, with scale of 2, but I want the second column to be a double as well.
Is there a way to force the datatype when creating a table through a standard make-table Access query?
One way to do it is to explicitly create the table before putting anything into it.
Your current statement is probably like this:
SELECT Persons.LastName,Orders.OrderNo
INTO Persons_Order_Backup
FROM Persons
INNER JOIN Orders
ON Persons.P_Id=Orders.P_Id
WHERE FirstName = 'Alistair'
But you can also do this:
----Create NewTable
CREATE TABLE NewTable(FirstName VARCHAR(100), LastName VARCHAR(100), Total DOUBLE)
----INSERT INTO NewTableusing SELECT
INSERT INTO NewTable(FirstName, LastName, Total)
SELECT FirstName, LastName,
FROM Person p
INNER JOIN Orders o
ON p.P_Id = o.P_Id
WHERE p.FirstName = 'Alistair'
This way you have total control over the column types. You can always drop the table later if you need to recreate it.
You can use the cast to FLOAT function CDBL() but, somewhat bizarrely, the Access Database Engine cannot handle the NULL value, so you must handle this yourself e.g.
SELECT first_column,
IIF(second_column IS NULL, NULL, CDBL(second_column))
AS second_column_as_float
INTO Table666
FROM MyTest;
...but you're going to need to ALTER TABLE to add your keys, constraints, etc. Better to simply CREATE TABLE first then use INSERT INTO..SELECT to populate it.
You can use CDbl around the columns.
An easy way to do this is to create an empty table with the correct field types and then to an Append-To query and Access will automatically convert the data to the destination field.
I had a similar situation, but I had a make-table query creating a field with NUMERIC datatype that I wanted to be short text.
What I did (and I got the idea from Stack) is to create the table with the field in question as Short Text, and at the same time build a delete query to scrub the records. I think it's funny that a DELETE query in access doesn't delete the table, just the records in it - I guess you have to use a DROP TABLE function for that, to purge a table...
Then, I converted my make-table query to an APPEND query, which I'd never done before... and I just added the running of the DELETE query to my process.
Thank you, Stack Overflow !
Steve
I add a '& ""' to the field I want to make sure are stored as text, and a ' *1 ' (as in multiplying the amount by 1) to the fields I want to store as numeric.
Seems to do the trick.
To get an Access query to create a table with three numeric output fields from input numeric fields, (it kept wanting to make the output fields text fields), had to combine several of the above suggestions. Pre-establish an empty output table with pre-defined output fields as integer, double and double. In the append query itself, multiply the numeric fields by one. It worked. Finally.