SQL: extract the last word - sql

I have a table that looks like the following:
id | cars
1 | John's Honda
2 | Andrew's red lexus
3 | James has a bmw
I need to just get the last word of the "cars" column that shows the actual "car" name
I have tried the followings but I don't get the desired output
select substr(cars, -1)
from t
the code above just shows me the last charater of the column. Later, I tried the following:
select split(cars, ' ')[offset(1)]
from t
however, I got the "Array index 1 is out of bounds (overflow)" error. Can anyone help how this can be achieved with bigquery?

Consider below simple approach
select *,
array_reverse(split(cars, ' '))[offset(0)] as brand
from your_table
if applied to sample data in your question - output is
Note: there are really many ways to accomplish your case - so anoher one would be regexp_extract(cars, r'\b(\w+)$') as brand

Related

SQL How do I get a part of a value that is between between specific left and right value

I would like to know what select statement can be used to get a piece of a column value that is between a specific value on the right and on the left.
Table contains the following information.
shipment_plsid
tag
element
1948
INCOTERMS
INCOTERMS VER="1">TYP>4/TYP>VAR>SHIPPER/VAR>/INCOTERMS>
2023
INCOTERMS
INCOTERMS VER="1">TYP>4/TYP>VAR>DDP/VAR>/INCOTERMS>
I need to retrieve the value for all records from column element that is between VAR> and /VAR.
Result should look like:
element
SHIPPER
DDP
Thanks
If you are using MySQL, this is what you need:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('VER="1">TYP>4/TYP>VAR>SHIPPER</VAR</INCOTERMS', "</VAR", 1), "VAR>", -1);
For example:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('VER="1">TYP>4/TYP>VAR>SHIPPER</VAR</INCOTERMS', "</VAR", 1), "VAR>", -1) as result;
+----------+
| result |
|----------|
| SHIPPER |
+----------+
1 row in set
Time: 0.011s
If you are using another db, please let us know which one it is
Use a SUBSTRING function and work out the start/length using CHARINDEX.
You have to add four characters to your first parameter to move start position to the end of the VAR> phrase. Similarly work out the length.
Here is a working solution:
select SUBSTRING(element,CHARINDEX('VAR>',element)+4,CHARINDEX('/VAR>',element)-CHARINDEX('VAR>',element)-4)from YourTable

Get row number of a row that meets an x condition in Postgresql

Hello Stack Overflow community, I wanted to get the row number of the first element that meets the condition specified in the query. I am making the queries using Postgresql and I send them from Python.
Here is an outline of what I want:
+--------+---------------+
|name |country |
|--------|---------------|
|Juan | United States |
|--------|---------------|
|Carlos | France |
|--------|---------------|
|Lucy | UK |
+--------+---------------+
In this case I would like to make a query where I can get the row number of the first person whose country is France (that is, row 2). Thank you. Anything that is not clear you can ask me.
I guess I rushed a little. Sorry.
I already found the solution. The following query worked for me:
SELECT num FROM (SELECT Row_Number() OVER () AS num, country FROM people ORDER BY country) AS tabla WHERE country='France'
with rownum as (
select *,
row_number() over() as rnum
from mytable
)
select min(rnum) as first_instance
from rownum
where country = 'France'
You can play around with this code on db-fiddle

Spitting long column values to managable size for presenting data neatly

Hi I was wondering if there is a way to split long column values in this case I am using SSRS to get the distinct values with the number of product ID against a category into a matrix/pivot table in SSRS. The problem lies with the amount of distinct category makes it a nightmare to make the report look pretty shall we say. Is there a dynamic way to split the columns in say groups of 10 to make the table look nicer and easy to read. I was thinking of using in operator then the list of values but that means managing the data every time a new category gets added. Is there a dynamic way to present the data in the best way possible? There are 135 distinct category values
Also I am open to suggestions to make the report to nicer if anyone has any thoughts. I am new to SSRS and trying to get to grips with its.
Here is an example of my problem
enter image description here
Are your column names coming back from the database under the SubCat field you note in the comments above? If so I imagine your dataset looks something like this
Subcat | Logno
---------+---------------
SubCatA | 34
SubCatB | 65
SubCatC | 120
SubCatD | 8
SubCatE | 19
You can edit this so that there is an index of each individual category being returned also, using the Row_Number() function. Add the field
ROW_NUMBER() OVER (ORDER BY SubCat ASC) AS ColID
To your query. This will result in the following.
Subcat | LogNo | ColID
-----------+--------------+----------
SubCatA | 34 | 1
SubCatB | 65 | 2
SubCatC | 120 | 3
SubCatD | 8 | 4
SubCatE | 19 | 5
Now there is a numeric identifier for each column you can perform some logic on it to arrange itself nicely on the page.
This solution involves a Tablix, nested inside a Matrix nested inside a Matrix as follows
First create a Matrix (Matrix1), and set it’s datasource to your dataset. Set the Row Group Properties to group on the following expression where ‘4’ is the number of columns you wish to display horizontally.
=CInt(Floor((Fields!ColID.Value - 1) / 4))
Then in the data section of the Matrix (bottom right corner) insert a rectangle and on this insert a new Matrix (Matrix 2). Remove the leftmost row. Set the column header to be the Column Name SubCat. This will automatically set the column grouping to be SubCat.
Finally, in the Data Section of Matrix 2 add a new Rectangle and Add a Tablix on it. Remove the Header Row, and set it to be one column wide only. Set the Data to be the information you wish to display, i.e. LogNo.
Finally, delete the Leftmost and Topmost rows/columns from Matrix 1 to make it look tidier (Note Delete Column Row only! Not associated groups!)
Then when the report is run it should look similar to the following. Note in my example SubCat = ColName, and LogNo = NumItems, and I have multiple values per SubCat.
Hopefully you find this helpful. If not, please ask for clarification.
Can you do something like this:
The following gives the steps (in two columns, down then across)

Moving data by length

I have to move words table's data to another tables.
For example words table is :
------------------------------
| word | type |
|------------------|---------|
| car | NA |
| home | NA |
| question | PR |
------------------------------
I have to move this data by length . For example , car's length is 3 , and car will move to 3-char table (with type column). And question will moved to 8-char .
How can i do it with SQL commands .
Sort of an incomplete question, but something like this might help point you in the right direction:
INSERT INTO words_3char SELECT word FROM all_words WHERE LENGTH(word)=3;
DELETE FROM all_words WHERE LENGTH(word)=3;
I'm not going to ask why you need to do all this moving around, but I'm not sure its a good idea. Assuming it is, take a look at the Length() function for mysql and then try something like this.
Insert into table_Char3(Word) Values (
Select Word from Words where Length(word) = 3)
You can move them to new tables like this
create table word1char as select word from words where length(trim(word)) = 1
..
create table word3chars as select word from words where length(trim(word)) = 3

How can I select only rows with multiple hits for a specific column?

I am not sure how to phrase this question so I'll give an example:
Suppose there is a table called tagged that has two columns: tagger and taggee. What would the SQL query look like to return the taggee(s) that are in multiple rows? That is to say, they have been tagged 2 or more times by any tagger.
I would like a 'generic' SQL query and not something that only works on a specific DBMS.
EDIT: Added "tagged 2 or more times by any tagger."
HAVING can operate on the result of aggregate functions. So if you have data like this:
Row tagger | taggee
--------+----------
1. Joe | Cat
2. Fred | Cat
3. Denise | Dog
4. Joe | Horse
5. Denise | Horse
It sounds like you want Cat, Horse.
To get the taggee's that are in multiple rows, you would execute:
SELECT taggee, count(*) FROM tagged GROUP BY taggee HAVING count(*) > 1
That being said, when you say "select only rows with multiple hits for a specific column", which row do you want? Do you want row 1 for Cat, or row 2?
select distinct t1.taggee from tagged t1 inner join tagged t2
on t1.taggee = t2.taggee and t1.tagger != t2.tagger;
Will give you all the taggees who have been tagged by more than one tagger