Full text search with Postgres - postgresql

How do I do a full text search in Postgres of all columns without preprocessing? I found http://www.postgresql.org/docs/9.3/static/textsearch-intro.html I'm not exactly sure what I need to do.
My initial impression is I need to auto concatenate each column (how do I do that? Can't find via Googling) put it in a WHERE and do ## to_tsquery
This is for https://github.com/timwis/node-soda2-parser/issues/1 I'm not concerned with bad performance
I tried starting with
select array_to_string(translate(string_to_array(r::text, ',')::text, '()', '')::text[], ' ')::tsvector FROM seattle_police_govqa_audit_trails as r LIMIT 1
But get:
{"readyState":4,"responseText":"{\"error\":[\"syntax error in tsvector: \\\"1 -1 -1 -1 -1 -1 0 0 1 1 2 3 3500 5 7007 198 1264 NULL NULL \\\"Answer created by staff\\\" NULL NULL \\\"9/24/2015 16:01\\\" A000198-092415\\\"\"]}","responseJSON":{"error":["syntax error in tsvector: \"1 -1 -1 -1 -1 -1 0 0 1 1 2 3 3500 5 7007 198 1264 NULL NULL \"Answer created by staff\" NULL NULL \"9/24/2015 16:01\" A000198-092415\""]},"status":400,"statusText":"Bad Request"}

select * FROM seattle_police_govqa_audit_trails as r WHERE regexp_replace(array_to_string(translate(string_to_array(r::text, ',')::text, '()', '')::text[], ' '), '[^a-zA-Z\s]', '', 'g')::tsvector ## 'created'::tsquery = true LIMIT 10

Related

Using DAX, I want to get only one value for multiple rows with same ID, and then run an IF statement over it

I am new to Power BI, I am facing issue where I want to create a new column based on the latest date and the id column
ID LogCreationDate Points What I want
1001 12-Oct-2022 5 null
1001 17-Oct-2022 2 2
1001 13-Oct-2022 7 null
1001 07-Aug-2022 2 null
1002 03-Sept-2022 2.1 null
1002 22-Sept-2022 5 null
1002 04-Oct-2022 1 1
1002 01-Aug-2022 1.2 null
1003 05-Nov-2022 3.5 3.5
1003 01-Nov-2022 6.6 null
In Above table, I want to calculate "What I want" column using DAX, not using power query
Try this Calculated Column:
=
REPT(
Table1[Points],
CALCULATE(
LASTDATE( Table1[LogCreationDate] ),
ALLEXCEPT( Table1, Table1[ID] )
) = Table1[LogCreationDate]
)
I think This is the best job for the measure, not the calc. column:
Please use this code:
what I want =
VAR TblSSS =
ADDCOLUMNS (
YourTbl,
"MaxDate",
CALCULATE (
LASTDATE ( YourTbl[LogCreationDate] ),
ALLEXCEPT ( YourTbl, YourTbl[ID] )
)
)
RETURN
MAXX ( TblSSS, IF ( [LogCreationDate] = [MaxDate], [Points], "null" ) )
If we test it on a table visual, It returns:
Note: After putting all fields and measure into suitable places, do not forget to click the down-pointing arrow on the id field, and pick 'show values with no data'.

oracle external table with date column and skip header

I have a file,
ID,DNS,R_D,R_A
1,123456,2014/11/17,10
2,987654,2016/05/20,30
3,434343,2017/08/01,20
that I'm trying to load to oracle using External Tables. I have to skip the header row and also load the date column.
This is my query:
DECLARE
FILENAME VARCHAR2(400);
BEGIN
FILENAME := 'actual_data.txt';
EXECUTE IMMEDIATE 'CREATE TABLE EXT_TMP (
ID NUMBER(25),
DNS VARCHAR2(20),
R_D DATE,
R_A NUMBER(25)
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY USER_DIR
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY '',''
MISSING FIELD VALUES ARE NULL
SKIP 1
(
"ID",
"DNS",
"R_D" date "dd-mon-yy",
"RECHARGE_AMOUNT"
)
)
LOCATION (''' || FILENAME || ''')
)
PARALLEL 5
REJECT LIMIT UNLIMITED';
END;
I get following exception:
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-00554: error encountered while parsing access parameters
KUP-01005: syntax error: found "skip": expecting one of: "column, exit, (,
reject"
KUP-01007: at line 4 column 5
ORA-06512: at "SYS.ORACLE_LOADER", line 19
I'm using sqlplus.
Could some oracle veterans please help me out and tell me what I'm doing wrong here? I'm very new to oracle.
You don't want to create any kind of tables (including external ones) in PL/SQL; not that it is impossible, but it is opposite of the best practices.
Have a look at my attempt, based on information you provided - works OK.
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> create table ext_tmp
2 (
3 id number,
4 dns varchar2(20),
5 r_d date,
6 r_a number
7 )
8 organization external
9 (
10 type oracle_loader
11 default directory kcdba_dpdir
12 access parameters
13 (
14 records delimited by newline
15 skip 1
16 fields terminated by ',' lrtrim
17 missing field values are null
18 (
19 id,
20 dns,
21 r_d date 'yyyy/mm/dd',
22 r_a
23 )
24 )
25 location ('actual_data.txt')
26 )
27 parallel 5
28 reject limit unlimited;
Table created.
SQL> select * from ext_tmp;
ID DNS R_D R_A
---------- -------------------- ---------- ----------
1 123456 17.11.2014 10
2 987654 20.05.2016 30
3 434343 01.08.2017 20
SQL>
In my case skip 1 didn't work even with placing it between records delimited by newline and fields terminated by ',' lrtrim until I used load when. Now skip 1 works with the following access parameters:
access parameters (
records delimited by newline
load when (someField != BLANK)
skip 1
fields terminated by '','' lrtrim
missing field values are null
reject rows with all null fields
)

SQL Server 2012 finding text before and after delimiter and sometimes without delimiter

I have been having fun with an issue where I need to break apart a string in SQL Server 2012 and test for values it may or may not contain. The values, when present, will be separated by up to two different ; symbols.
When there is nothing, it will be blank.
When there is a single value, it will show up without the delimiter.
When there are two or more, up to 3, they will be separated by the delimiter.
As I said, if there is nothing in the record, it will be blank. Below are some example of how the data may come across:
' ',
'1',
'24',
'15;1;24',
'10;1;22',
'5;1;7',
'12;1',
'10;12',
'1;5',
'1;1;1',
'15;20;22'
I have searched the forums and found many clues, but I have not been able to come up with a total solution given all potential data values. Essentially, I would like to break it into 3 separate values.
text before the first delimiter or in the absence of the delimiter, just the text.
Text after the first delimiter and before the second in situation where there are two delimiters.
The following has worked consistently:
substring(SUBSTRING(Food_Desc, charindex(';', Food_Desc) + 1, 4), 0,
charindex(';', SUBSTRING(Food_Desc, charindex(';', Food_Desc) + 1, 4))) as [Middle]
Text after the second delimiter in the even there are two delimiters and there is a third value
The main challenge is the fact that the delimiter, when present, moves depending on the value in the table. values 1-9 make it show up as the second character in the string, values 10-24 make it show up as the 3rd, etc.
Any help would be greatly appreciated.
This is simple if you have a well written t-sql splitter function. For this solution I'm using Jeff Moden's delimitedsplit8k.
sample data and solution
DECLARE #table table (someid int identity, sometext varchar(100));
INSERT #table VALUES (' '),('1'),('24'),('15;1;24'),('10;1;22'),
('5;1;7'),('12;1'),('10;12'),('1;5'),('1;1;1'),('15;20;22');
SELECT
someid,
sometext,
ItemNumber,
Item
FROM #table
CROSS APPLY dbo.DelimitedSplit8K_LEAD(sometext, ';');
results
someid sometext ItemNumber Item
----------- ----------------- ----------- --------
1 1
2 1 1 1
3 24 1 24
4 15;1;24 1 15
4 15;1;24 2 1
4 15;1;24 3 24
5 10;1;22 1 10
5 10;1;22 2 1
5 10;1;22 3 22
6 5;1;7 1 5
6 5;1;7 2 1
6 5;1;7 3 7
7 12;1 1 12
7 12;1 2 1
8 10;12 1 10
8 10;12 2 12
9 1;5 1 1
9 1;5 2 5
10 1;1;1 1 1
10 1;1;1 2 1
10 1;1;1 3 1
11 15;20;22 1 15
11 15;20;22 2 20
11 15;20;22 3 22
Below is a modified version of a similar question How do I split a string so I can access item x?. Changing the text value for #sample to each of your possibilities listed seemed to work for me.
DECLARE #sample VARCHAR(200) = '15;20;22';
DECLARE #individual VARCHAR(20) = NULL;
WHILE LEN(#sample) > 0
BEGIN
IF PATINDEX('%;%', #sample) > 0
BEGIN
SET #individual = SUBSTRING(#sample, 0, PATINDEX('%;%', #sample));
SELECT #individual;
SET #sample = SUBSTRING(#sample, LEN(#individual + ';') + 1, LEN(#sample));
END;
ELSE
BEGIN
SET #individual = #sample;
SET #sample = NULL;
SELECT #individual;
END;
END;

Transactional Replication: Column name or number of supplied values does not match table definition

I have set up a transactionnal replication for some tables.
The Master and the Slave Database are identical.
I used this query and compared the result from master and slave to make sure the table is identical
select * from sys.columns c
join sys.tables t on t.object_id = c.object_id
where t.name = 'customers'
In the Replication Monitor I can find this error:
Column name or number of supplied values does not match table definition.
If I check the details I get this:
Command attempted:
if ##trancount > 0 rollback tran
(Transaction sequence number: 0x0011775200000105007600000000, Command ID: 1)
So I checked in the destribution database using this query to find the command that is failing.
sp_browsereplcmds #xact_seqno_start = '0x0011775200000105007600000000',
#xact_seqno_end = '0x0011775200000105007600000000'
This is the command (its in 2 lines in that table):
{CALL [sp_MSins_dboCustomers] (0,'575',N'todelete','575',N'todelete',118594,118595,118596,N'10T 3% Sk 30T net.',0,'Deutschland',4,24399158193054E-314,4,24399158193054E-314,4,24399158193054E-314,4,24399158193054E-314,2,54639494915833E-313,'','','','','','TGW',N'Liefern LKW',NULL,NULL,0,0,6,79038653108887E-311,NULL,'',0,NULL,NULL,NULL,0,0,0,-1,-1,1900-01-01 00:00:00,0,1,{AEB3D911-36D1-4A8A-B713-6B2F2CCA1641},0,0,2,'de-AT',25,NULL,NULL,0,1,NULL,NULL,2014-03-07 08:57:45.727,-1,NULL,0,'','','','','','','','','','','','',
'','','','','','','','')}
This is what I have in my DB
TypeID CustomerID Name SiteID SiteName AddressID BillAddressID ShipAddressID Terms TaxExempt TaxSchedID TaxPercent TaxPercent1 TaxPercent2 TaxPercent3 TaxPercent4 TaxTitle TaxTitle1 TaxTitle2 TaxTitle3 TaxTitle4 LocationID ShipVia PackingType PackingNoteID CutoffDay UploadAction LeadTime ExpDays Notes SalesPersonID CreditLimit OpenOrders OrderValueScheduleID OAHidePrices DefaultAckType DefaultInvType DefaultPackType UploadEmployee UploadDateTime OAHideImages MfgCustomer CustomerGUID PricingMethod DefaultCustomer EngineeringUnitSetID CurrencyCulture FamilyGroupID InvoiceMinimum InvoiceSurcharge InvoiceGroup InvoiceCopies DeliveryMinimum DeliverySurcharge CreateDate EnteredBy LanguageCulture DropShip UserDef1 UserDef2 UserDef3 UserDef4 UserDef5 UserDef6 UserDef7 UserDef8 UserDef9 UserDef10 UserDef11 UserDef12 UserDef13 UserDef14 UserDef15 UserDef16 UserDef17 UserDef18 UserDef19 UserDef20
0 575 todelete 575 todelete 118594 118595 118596 10T 3% Sk 30T net. 0 Deutschland 0 0 0 0 0 TGW Liefern LKW NULL NULL 0 0 0 NULL 302 NULL NULL NULL 0 0 0 -1 -1 1900-01-01 00:00:00 0 1 AEB3D911-36D1-4A8A-B713-6B2F2CCA1641 0 0 2 de-AT 25 NULL NULL 0 1 NULL NULL 2014-03-07 08:57:45.727 -1 NULL 0 1 2 3 4 0 1 2 3 4
As you can see here, the values for the taxpercent fields (after "Deutschland") are 0 in my DB, in the command they are really weird (4,24399158193054E-314)
The Datatype is "real"
Maybe this is not the issue but this is the only weird thing I could find.
I found my problem.
In fact this 4,24399158193054E-314 is a value for "0" in real, the problem is that it did not use the "." but the "," as decimal separator and therefore the call of the procedure had too much argument.
What I did is to change the statement delivery for insert, update, delete from "Call " to INSERT/UPDATE/DELETE statement.
I don't know why this is not selected by default, but now it works.

tsql how to validate a number's scale

I need to validate the number of digits to the right of the decimal (the scale)
0, is a valid number in any of the places (tenths, hundredths, thousandths, etc.).
Any tips or tricks?... w/o an extensive regex library, and no built in function, I would prefer a function that accepts the number, the number of places the scale should equal, and then return a bit.
Following up with Maess's suggestion I came up with this:
CREATE FUNCTION [dbo].[GetScale]
(
#tsValue varchar(250)
, #tiScale int
)
RETURNS int
AS
BEGIN
DECLARE
#tiResult int
, #tiValueScale int
SET #tiResult = 0
SELECT #tiValueScale = LEN( SUBSTRING ( #tsValue, PATINDEX('%.%', #tsValue) + 1, LEN(#tsValue) ) )
IF (#tiValueScale = #tiScale)
SET #tiResult = 1
RETURN #tiResult
END
GO
Seems to work as desired. Thanks for the help.
Just as a followup... i ran into an issue where a number didnt have a decimal (which returns the patindex to 0) and the number was the same size as the scale, it would return a false positive... so i add an additional select from the patindex to determine if it does exist or not... it now looks like this:
- =============================================
ALTER FUNCTION [dbo].[GetScale]
(
#tsValue varchar(250)
, #tiScale int
)
RETURNS int
AS
BEGIN
DECLARE
#tiResult int
, #tiValueScale int
, #tiDecimalExists int
SET #tiResult = 0
SET #tiDecimalExists = 0
SELECT #tiDecimalExists = PATINDEX('%.%', #tsValue)
IF (#tiDecimalExists != 0)
BEGIN
SELECT #tiValueScale = LEN( SUBSTRING ( #tsValue, #tiDecimalExists + 1, LEN(#tsValue) ) )
IF (#tiValueScale = #tiScale)
SET #tiResult = 1
END
RETURN #tiResult
END
I tried Anthony's solution with some success, but there is some undesirable side effects when the first whole number is 9.
For example...
select 0.11 as fraction, Math.NumberOfDecimalPlaces(0.11) dp union
select 9.1, Math.NumberOfDecimalPlaces(9.1) union
select 9.01, Math.NumberOfDecimalPlaces(9.01) union
select 9.0, Math.NumberOfDecimalPlaces(9.0) union
select 99.0, Math.NumberOfDecimalPlaces(99.0) union
select 10999.0, Math.NumberOfDecimalPlaces(10999.0) union
select 8.0, Math.NumberOfDecimalPlaces(8.0) union
select 0, Math.NumberOfDecimalPlaces(0)
Produces...
0.00 0
0.11 2
8.00 0
9.00 -1
9.01 2
9.10 1
99.00 -2
10999.00 -3
Which shows some incorrect calculations when 9 is the first whole number.
I've made a small improvement to Anthony's original function.
CREATE FUNCTION [Math].[NumberOfDecimalPlaces]
(
#fraction decimal(38,19)
)
RETURNS INT
AS
BEGIN
RETURN FLOOR(LOG10(REVERSE(ABS(#fraction % 1) +1))) +1
END
This simply strips of the whole number part of the fraction. Which when implemented produces...
0.00 0
0.11 2
8.00 0
9.00 0
9.01 2
9.10 1
99.00 0
10999.00 0
The correct result
CREATE FUNCTION dbo.DecimalPlaces(#n decimal(38,19))
RETURNS int
AS
BEGIN
RETURN FLOOR(LOG10(REVERSE(ABS(#n % 1) + 1))) + 1
END
Edit (Feb 5 '15):
Thanks sqlconsumer. I have included your fix for nines before the decimal point.