我是 Snowflake SQL 的新手,正在尝试将代码从 Oracle SQL 迁移到 Snowflake SQL。
我在 Oracle 中使用了 Snowflake 不支持的子查询,它给出了以下 err-r
<块引用>SQL 编译错误:无法评估不受支持的子查询类型。
原始 SQL 查询 -
import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
import 'package:audioplayers/notifications.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class PlayerWidget extends StatefulWidget {
final String url;
final PlayerMode mode;
const PlayerWidget({
Key? key,
required this.url,
this.mode = PlayerMode.MEDIA_PLAYER,
}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _PlayerWidgetState(url, mode);
}
}
class _PlayerWidgetState extends State<PlayerWidget> {
String url;
PlayerMode mode;
late AudioPlayer _audioPlayer;
PlayerState? _audioPlayerState;
Duration? _duration;
Duration? _position;
PlayerState _playerState = PlayerState.STOPPED;
PlayingRoute _playingRouteState = PlayingRoute.SPEAKERS;
StreamSubscription? _durationSubscription;
StreamSubscription? _positionSubscription;
StreamSubscription? _playerCompleteSubscription;
StreamSubscription? _playerErrorSubscription;
StreamSubscription? _playerStateSubscription;
StreamSubscription<PlayerControlCommand>? _playerControlCommandSubscription;
bool get _isPlaying => _playerState == PlayerState.PLAYING;
bool get _isPaused => _playerState == PlayerState.PAUSED;
String get _durationText => _duration?.toString().split('.').first ?? '';
String get _positionText => _position?.toString().split('.').first ?? '';
bool get _isPlayingThroughEarpiece =>
_playingRouteState == PlayingRoute.EARPIECE;
_PlayerWidgetState(this.url, this.mode);
@override
void initState() {
super.initState();
_initAudioPlayer();
}
@override
void dispose() {
_audioPlayer.dispose();
_durationSubscription?.cancel();
_positionSubscription?.cancel();
_playerCompleteSubscription?.cancel();
_playerErrorSubscription?.cancel();
_playerStateSubscription?.cancel();
_playerControlCommandSubscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
key: const Key('play_button'),
onPressed: _isPlaying ? null : _play,
iconSize: 64.0,
icon: const Icon(Icons.play_arrow),
color: Colors.cyan,
),
IconButton(
key: const Key('pause_button'),
onPressed: _isPlaying ? _pause : null,
iconSize: 64.0,
icon: const Icon(Icons.pause),
color: Colors.cyan,
),
IconButton(
key: const Key('stop_button'),
onPressed: _isPlaying || _isPaused ? _stop : null,
iconSize: 64.0,
icon: const Icon(Icons.stop),
color: Colors.cyan,
),
IconButton(
onPressed: _earpieceOrSpeakersToggle,
iconSize: 64.0,
icon: _isPlayingThroughEarpiece
? const Icon(Icons.volume_up)
: const Icon(Icons.hearing),
color: Colors.cyan,
),
],
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Stack(
children: [
Slider(
onChanged: (v) {
final Position = v * _duration!.inMilliseconds;
_audioPlayer
.seek(Duration(milliseconds: Position.round()));
},
value: (_position != null &&
_duration != null &&
_position!.inMilliseconds > 0 &&
_position!.inMilliseconds <
_duration!.inMilliseconds)
? _position!.inMilliseconds / _duration!.inMilliseconds
: 0.0,
),
],
),
),
Text(
_position != null
? '$_positionText / $_durationText'
: _duration != null
? _durationText
: '',
style: const TextStyle(fontSize: 24.0),
),
],
),
Text('State: $_audioPlayerState'),
],
);
}
void _initAudioPlayer() {
_audioPlayer = AudioPlayer(mode: mode);
_durationSubscription = _audioPlayer.onDurationChanged.listen((duration) {
setState(() => _duration = duration);
if (Theme.of(context).platform == TargetPlatform.iOS) {
// optional: listen for notification updates in the background
_audioPlayer.notificationService.startHeadlessService();
// set at least title to see the notification bar on ios.
_audioPlayer.notificationService.setNotification(
title: 'App Name',
artist: 'Artist or blank',
albumTitle: 'Name or blank',
imageUrl: 'Image URL or blank',
forwardSkipInterval: const Duration(seconds: 30), // default is 30s
backwardSkipInterval: const Duration(seconds: 30), // default is 30s
duration: duration,
enableNextTrackButton: true,
enablePreviousTrackButton: true,
);
}
});
_positionSubscription =
_audioPlayer.onAudioPositionChanged.listen((p) => setState(() {
_position = p;
}));
_playerCompleteSubscription =
_audioPlayer.onPlayerCompletion.listen((event) {
_onComplete();
setState(() {
_position = _duration;
});
});
_playerErrorSubscription = _audioPlayer.onPlayerError.listen((msg) {
print('audioPlayer error : $msg');
setState(() {
_playerState = PlayerState.STOPPED;
_duration = const Duration();
_position = const Duration();
});
});
_playerControlCommandSubscription =
_audioPlayer.notificationService.onPlayerCommand.listen((command) {
print('command: $command');
});
_audioPlayer.onPlayerStateChanged.listen((state) {
if (mounted) {
setState(() {
_audioPlayerState = state;
});
}
});
_audioPlayer.onNotificationPlayerStateChanged.listen((state) {
if (mounted) {
setState(() => _audioPlayerState = state);
}
});
_playingRouteState = PlayingRoute.SPEAKERS;
}
Future<int> _play() async {
final playPosition = (_position != null &&
_duration != null &&
_position!.inMilliseconds > 0 &&
_position!.inMilliseconds < _duration!.inMilliseconds)
? _position
: null;
final result = await _audioPlayer.play(url, position: playPosition);
if (result == 1) {
setState(() => _playerState = PlayerState.PLAYING);
}
// default playback rate is 1.0
// this should be called after _audioPlayer.play() or _audioPlayer.resume()
// this can also be called everytime the user wants to change playback rate in the UI
_audioPlayer.setPlaybackRate();
return result;
}
Future<int> _pause() async {
final result = await _audioPlayer.pause();
if (result == 1) {
setState(() => _playerState = PlayerState.PAUSED);
}
return result;
}
Future<int> _earpieceOrSpeakersToggle() async {
final result = await _audioPlayer.earpieceOrSpeakersToggle();
if (result == 1) {
setState(() => _playingRouteState = _playingRouteState.toggle());
}
return result;
}
Future<int> _stop() async {
final result = await _audioPlayer.stop();
if (result == 1) {
setState(() {
_playerState = PlayerState.STOPPED;
_position = const Duration();
});
}
return result;
}
void _onComplete() {
setState(() => _playerState = PlayerState.STOPPED);
}
}
我重新构建了查询,它编译并提供了相同数量的记录,任何人都可以查看代码并评论它是否相同或正确,请评论相同。
select p."EMPLOYEE#" as Employee_ID,
(select o."POSITION_NO" from ah_occupancy o where o."EMPLOYEE_NO" = p."EMPLOYEE#" and o."JOB_NO" = p."JOB#" and p."WORKDATE" between o."PORTION_START" and o."PORTION_END") as Position_ID,
j."COMPANY_CODE",
date(p."WORKDATE") as Work_Date,
p."UNIT" as Calculated_Quantity,
p."PAYCODE"
from
"ODS"."HRIS"."PEPAYTRAN" p, job j
where p."EMPLOYEE#" =j."EMPLOYEE#"
and p."JOB#" = j."JOB#"
and date( p."WORKDATE") between '2021-02-04' and '2021-02-10'-->='11-FEB-2021'
and p."ORIGIN" not in ('RC101','FC801','WK8276')
and p."PAYCODE" not in ('GPPL', 'CLAMS')
and p."PAYCODE" not like 'JK%'
and p."TP" >= '01-JAN-2021'
and nvl(p."BATCH#",' ') not in ('MUHTSL','MUHTS','ICWTS','RDOAC','NU011','1')) ;
答案 0 :(得分:0)
两个查询是等价的。您可以通过运行以下查询来检查两者是否返回相同的信息:
--original query
select
p."EMPLOYEE#" as Employee_ID,
(select
o."POSITION_NO"
from
ah_occupancy o
where
o."EMPLOYEE_NO" = p."EMPLOYEE#"
and o."JOB_NO" = p."JOB#"
and p."WORKDATE" between o."PORTION_START" and o."PORTION_END"
) as Position_ID,
j."COMPANY_CODE",
date(p."WORKDATE") as Work_Date,
p."UNIT" as Calculated_Quantity,
p."PAYCODE"
from
"ODS"."HRIS"."PEPAYTRAN" p,
job j
where
p."EMPLOYEE#" =j."EMPLOYEE#"
and p."JOB#" = j."JOB#"
and date( p."WORKDATE") between '2021-02-04' and '2021-02-10'-->='11-FEB-2021'
and p."ORIGIN" not in ('RC101','FC801','WK8276')
and p."PAYCODE" not in ('GPPL', 'CLAMS')
and p."PAYCODE" not like 'JK%'
and p."TP" >= '01-JAN-2021'
and nvl(p."BATCH#",' ') not in ('MUHTSL','MUHTS','ICWTS','RDOAC','NU011','1')) ;
minus
--new query
select
p."EMPLOYEE#" as Employee_ID,
o.position_no as Position_ID,
j."COMPANY_CODE",
date(p."WORKDATE") as Work_Date,
p."UNIT" as Calculated_Quantity,
p."PAYCODE"
from
"ODS"."HRIS"."PEPAYTRAN" p,
"ODS"."HRIS"."JOB" j,
"ODS"."HRIS"."AH_OCCUPANCY" o
where
p."EMPLOYEE#" =j."EMPLOYEE#"
and p."JOB#" = j."JOB#"
and date( p."WORKDATE") between '2021-02-04' and '2021-02-10'-->='11-FEB-2021'
and p."ORIGIN" not in ('RC101','FC801','WK8276')
and p."PAYCODE" not in ('GPPL', 'CLAMS')
and p."PAYCODE" not like 'JK%'
and p."TP" >= '01-JAN-2021'
and nvl(p."BATCH#",' ') not in ('MUHTSL','MUHTS','ICWTS','RDOAC','NU011','1')
and o."EMPLOYEE_NO" = p."EMPLOYEE#"
and o."JOB_NO" = p."JOB#"
and p."WORKDATE" between o."PORTION_START" and o."PORTION_END"
您也可以尝试以下同样等效的查询:
select
p."EMPLOYEE#" as Employee_ID,
o.position_no as Position_ID,
j."COMPANY_CODE",
date(p."WORKDATE") as Work_Date,
p."UNIT" as Calculated_Quantity,
p."PAYCODE"
from
"ODS"."HRIS"."PEPAYTRAN" p
inner join "ODS"."HRIS"."JOB" j
on (p."EMPLOYEE#" =j."EMPLOYEE#"
and p."JOB#" = j."JOB#")
inner join "ODS"."HRIS"."AH_OCCUPANCY" o
on (o."EMPLOYEE_NO" = p."EMPLOYEE#"
and o."JOB_NO" = p."JOB#"
and p."WORKDATE" between o."PORTION_START" and o."PORTION_END" )
where
date( p."WORKDATE") between '2021-02-04' and '2021-02-10'-->='11-FEB-2021'
and p."ORIGIN" not in ('RC101','FC801','WK8276')
and p."PAYCODE" not in ('GPPL', 'CLAMS')
and p."PAYCODE" not like 'JK%'
and p."TP" >= '01-JAN-2021'
and nvl(p."BATCH#",' ') not in ('MUHTSL','MUHTS','ICWTS','RDOAC','NU011','1')