2016年3月28日月曜日

外部結合してDelete

delete文に外部結合を使うには、癖があります。

通常のdelete文は、こんな感じ

delete table1
where table1.column = ?

外部結合してのdelete文はこんな感じ

delete table1, table2
from table1
left join table2 on table1.id = table2.id
where table1.column = ?
 
通常のdelete文には使わない、from句 を使うのです。
 
知らずにSQLエラーが多発して苦しみました。
ちゃんとマニュアルかグーグル先生を頼りましょう
 
 
 

2016年2月8日月曜日

viコマンド

久しぶりで忘れていたので、最低限必要なコマンドだけを


・編集モードとコマンドモード
コマンドモード:起動直後、Escキー
編集モード:文字入力の状態。カーソルキーで移動は可能

・終了方法
:q! 変更を保存せず終了
:w 保存のみ
:wq 保存して終了

・文字入力
i カーソル位置から文字挿入
o カーソル行の次の行に行挿入してから文字入力

・文字削除
x 一文字削除
dd カーソル行削除

2014年6月11日水曜日

VBA 一意なリストの高速作成

一意なリストとは、列に重複したレコードが存在した場合、重複を排除したレコードの一覧のこと。
SQLでいえば、distinct のことです。

Excelの画面操作では、以下の手順で作成(わかりやすく1列で操作)

1)重複したレコードを含む範囲を選択
2)データ → フィルタ → フィルタオプションの設定
3)"重複するレコードは無視する"にチェックを入れる
4)OK ボタンをクリック

Excelのフィルタ機能で、リストが一意になるように、重複したレコードは非表示になります。
しかし、大量データでは遅いのと、あくまで非表示にしているだけなので、使い勝手が悪いです。
そこで、VBAで一意なリストを作成します。


<前提>
重複したリスト Sheet1 A列にA1から格納されている
一意なリストはSheet2のA列に作成する

Dim myDic As Object, myKey As Variant
Dim c As Variant, varData As Variant

Set myDic = CreateObject("Scripting.Dictionary")
'                                ↓重複したリストのシート名
With Worksheets("Sheet1")
'                   ↓重複したリストの範囲
  varData = .Range("A1", .Range("A" & Rows.Count).End(xlUp)).Value
End With

For Each c In varData
  If Not c = Empty Then
    If Not myDic.Exists(c) Then
      myDic.Add c, Null
    End If
  End If
Next

myKey = myDic.Keys
'                                  ↓一意なリストを作成するシート名
With Worksheets("Sheet2")
'                ↓A列をクリア
  .Range("A:A").ClearContents
'                ↓一意なリストを作成
  .Range("A1").Resize(myDic.Count) = Application.WorksheetFunction.Transpose(myKey)
End With

Set myDic = Nothing

2014年6月2日月曜日

Netezza(ネティーザ) Oracleでいうところの dual表

OracleでダミーのSQLを実行する時によく使う dual テーブルがあります。

当然、Netezzaには dual テーブルはありませんが、ダミーのSQLを実行する方法はあります。

・Oracle の場合
select to_char(sysdate,'YYYY-MM-DD') from dual;

・Netezza の場合
select to_char(now(),'YYYY/MM/DD') ;

from 句を省略することで、同じ動きをします。



2014年5月30日金曜日

VBA 必要な行にだけ関数を設定

何行データがあるかわからないシートに、データのある行にだけ、関数をセットしたいことはよくある。

簡単なのはあらかじめ適用な行数分、関数をセットしておくことですが、ちゃんと必要な行数分関数がセットされているか確認しないと漏れてしまう。

それをマクロで自動設定する。

'最終行を取得
checkcol = 4
lastrow = Cells(Rows.Count , checkcol ).End(xlUp).row

'先頭行のセルに関数をセット
startrow = 3
setcol = 3
Cells(startrow,setcol).Value = "row() - " & startcol + 1

'関数を必要な行数分コピー
Cells(startrow,setcol).Copy
Range(Cells(startrow,setcol),Cells(lastrow,setcol).Select
ActiveSheet.Paste



VBA 最後の行取得とループ処理

値の入っている表に対して、値の入っている一番最後の行を取得して処理を行う。

・値の入っている最後の行 
例)B列に値が設定されている一番最後の行番号
'値が入っていることを評価する列番号 2=B列
col = 2 
lastrow = Cells(Rows.Count , col ).End(xlUp).row

・最後の行までループ処理
例)3行目からD列に値が設定されている一番最後の行までループして、A列に番号をセットする

startrow = 3
checkcol = 4
rownum = 1
lastrow = Cells(Rows.Count , checkcol ).End(xlUp).row

for row = startrow to lastrow
    Cells(row , 1).Value = rownum
    rownum = rownum + 1

Next row

2014年5月29日木曜日

Netezza(ネティーザ) 項目一覧

IBMのDB、Netezzaで、Oracleの user_tab_columns のように、テーブル一覧を取得する。

_V_RELATION_COLUMN
OWNER : オーナー
NAME : テーブル名
ATTNUM : 項目番号
ATTNAME : 項目名
FORMAT_TYPE : 項目型(桁、小数桁)
ATTCOLLENG : 項目長
ATTNOTNULL : Null('t'=NotNull / 'f'=Null)

_V_DOTNET_PRIMARYKEYS1
TABLE_SCHEMA : テーブルスキーマ
TABLE_NAME : テーブル名
COLUMN_NAME : 項目名
KEY_SEQ : プライマリーキー項目順
PK_NAME  : プライマリーキー名

* プライマリーキーの情報がどこに格納されているか不明だったが、とりあえずデータを見つけられたので採用。他環境でも同様に取得できるかは不明。

select
A.OWNER
,A.NAME
,A.ATTNUM
,A.ATTNAME
,A.FORMAT_TYPE
,A.ATTCOLLENG
,A.ATTNOTNULL
,B.KEY_SEQ
 from _V_RELATION_COLUMN A
left outer join _V_DOTNET_PRIMARYKEYS1 B
on A.NAME = B.TABLE_NAME
and A.ATTNAME = B.COLUMN_NAME
;

このままでは、桁と小数桁が項目型に混じってしまっているため切りだす。

select
A.OWNER
,A.NAME
,A.ATTNUM
,A.ATTNAME
,case
when position('(' in A.FORMAT_TYPE) != 0 
  then substr(A.FORMAT_TYPE,1,position('(' in A.FORMAT_TYPE)-1)
 else A.FORMAT_TYPE
end as ATTFORMAT  
,case 
when substr(A.FORMAT_TYPE,1,4) = 'NUME'
  then to_number(translate(substr(A.FORMAT_TYPE,9,2),',',''),'99')
else A.ATTCOLLENG
end as ATTLENGTH
,case 
when substr(A.FORMAT_TYPE,1,4) = 'NUME'
  then to_number(substr(A.FORMAT_TYPE,position(',' in A.FORMAT_TYPE) + 1 ,1),'9')
else 0
end as ATTSCALE
,case
when A.ATTNOTNULL = 't' then 'NotNull'
else 'Null'
end as ATTNULL
,B.KEY_SEQ
 from _V_RELATION_COLUMN A
left outer join _V_DOTNET_PRIMARYKEYS1 B
on A.NAME = B.TABLE_NAME
and A.ATTNAME = B.COLUMN_NAME
;